变量类型
变量类型控制访问权限

规则
对象变量的类型 可以跟 对象的类型不一致
等号左边 对象变量的类型 决定 可以调用哪些方法
理解
animal 持有 Person 对象, 但只有 Animal 类型的访问权限
animal 是一个人, 但我把ta暂时看成动物
对象变量类型转换
走近科学
苹果树上长桃子的故事
向父类型转Upcasting
规则
X x = new Y();
Y y = ...; X x = y;
Y 可以是 X 自己,或者是 X 的 直接/间接子类
X 可以是 Y 自己,或者是 Y 的 直接/间接父类
案例
1 2 Person person = new Person();Animal animal = person;
效果
创建一个新的变量, 具有低级别访问权限
对象没有复制 更没有被转成别的类型
向子类转型Downcasting
规则
Y y = ...; X x = (X)y;
X 是 Y 自己,或者是 Y 的 直接/间接子类 时,
需要些 写强制类型转换,强制转型,才能通过编译
运行时, 会检查是否真的能被转换, 如果不能, 会报错
案例
1 2 Animal animal = new Person();Person person = (Person)animal;
效果
创建一个新的变量, 恢复高级别访问权限
二次检查
Y y = new Z(); X x = (X)y;
编译时
X 是不是 Y 的自己、子类、间接子类
运行时
X 是不是 Z 的自己、父类、间接父类
向其它类型转型
案例 1
1 2 Person person = new Person();Dog dog = (Dog) person;
强制类型转换也没用
不允许这么写
案例 2
1 2 3 Person person = new Person();Animal animal = person;Dog dog = (Dog) animal;
能绕过编译检查,
但运行时, 会崩溃
练习
1 2 3 4 5 6 7 8 9 10 11 Person person = new Person();person.eat();person.work();Animal animal = person;animal.eat();animal.work();Person person2 = animal;Person person3 = (Person)animal;Dog dog = animal;Dog dog2 = (Dog) animal;Dog dog3 = (Dog) person;
对象类型检测
问题
1 2 3 4 5 6 7 8 9 10 11 public class Driver { public void run() { Person p = new Person(); feed(p); } public void feed(Animal animal) { Person p = (Person) animal; p.work(); }}
getClass
用来检测 a 所指的对象到底是谁
改进代码
1 2 3 4 5 6 7 8+9 10 11+12 13 public class Driver { public void run() { Person p = new Person(); feed(p); } public void feed(Animal animal) { if (animal.getClass() == Person.class) { Person p = (Person) animal; p.work(); } }}