Java自学---理解多态
介绍
父类引用指向子类对象。出现相同类型的变量、调用同一个方法时呈现出多种不同的行为特征。
// 格式
父类名称 对象名=new 子类名称();
或者
接口名称 对象名=new 实现类名称();
通过一个例子来分析:
public class Multi {
public static void main(String[] args) {
Fu obj = new Zi();
System.out.println(obj.num);
obj.method();
}
}
//父类
public class Fu {
int num = 10;
public void method(){
System.out.println(num);
}
}
//子类
public class Zi extends Fu{
int num = 20;
@Override
public void method(){
System.out.println(num);
}
}
// 结果
10
20
obj的编译时类型为—Fu,运行时类型为—Zi。
引用变量在编译阶段只能调用其编译时所具有的方法,但运行时则执行它运行时类型所具有的方法。因此,obj在编译阶段调用的是Fu的method方法,而在实际运行后,由于Zi类重写了method方法,所以运行结果是Zi类的method方法得出的结果。
如果Fu类中没有method方法,而子类中有method方法,该段代码会在编译时出错。
与方法不同,对象的实例变量不具备多态性。如Fu类中定义的num=10,Zi类中定义的num=20,引用变量obj在程序中输出num实例变量时,输出的是Fu类的实例变量。
口诀:
引用变量------编译看左边,运行看右边
实例变量------编译看左边,运行看左边
“左”指的是等号左边的类型
若需要引用变量调用它运行时类型的方法,则可使用类型转换运算符进行强制类型转换—(type)variable,将variable转换成type类型。
不过有几点需要注意:
- 数值类型和布尔类型之间不能进行类型转换。
- 引用类型之间的转换只能在具有继承关系的两个类型之间进行,如上例,可进行转换:Zi 对象 = (Zi)Fu的对象。
instanceof运算符
考虑到强制类型转换可能出现异常,因此进行强制类型转换之前应先通过instanceof运算符来判断是否可以成功转换,保证程序健壮性。
//格式
(引用类型变量 instanceof 类/接口),判断前面的对象是否是后面的类,或者其子类、实现类的实例。是,返回true,否则返回false。
例 if(obj instanceof Zi){//...}