5.7 多态 5.7.1 多态性
引用变量的类型
Java
引用变量有两个类型:
- 一个是
编译时类型
,
- 一个是
运行时类型
。
编译时类型
就是声明该引用变量时使用的类型
运行时类型
就是该引用变量所引用的实际对象的类型
,一般通过new
关键字来创建对象,new
关键字后面的类型就是运行时类型.
例如: Person p=new Chinese();
这行代码,引用变量p
的
- 编译时类型是父类
Person
,
- 运行时类型是子类
Chinese
如果编译时类型和运行时类型不一致,就可能出现所谓的多态(Polymorphism
)。
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象
多态方法调用方法时如何确定调用的是哪个方法
当使用多态方式调用方法时,首先检查父类中是否有该方法,
- 如果父类中没有,则编译错误;
- 如果父类中有,再去调用子类的
重写的
同名方法。如果子类没有重写该方法,则调用子类继承得到的方法,也就是父类的方法.
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| class BaseClass { public int book = 1024;
public void base() { System.out.println("父类 实例方法 base()"); }
public void test() { System.out.println("父类 实例方法 test()"); } }
class A extends BaseClass { public String book = "子类A 实例变量";
public void test() { System.out.println("子类A 实例方法 test()"); } }
public class SubClass extends BaseClass { public String book = "子类1 实例变量";
public void test() { System.out.println("子类 重写的实例方法 test()"); }
public void sub() { System.out.println("子类 自己定义的方法 sub()"); }
public static void main(String[] args) { BaseClass bc = new BaseClass(); System.out.println(bc.book); bc.base(); bc.test(); System.out.println("-------------------------------"); SubClass sc = new SubClass(); System.out.println(sc.book); sc.base(); sc.test(); System.out.println("-------------------------------"); BaseClass ploymophicBc = new SubClass(); System.out.println(ploymophicBc.book); ploymophicBc.base(); ploymophicBc.test(); System.out.println("---------------------------------"); ploymophicBc = new A(); System.out.println(ploymophicBc.book); ploymophicBc.test(); } }
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 1024 父类 实例方法 base() 父类 实例方法 test() ------------------------------- 子类1 实例变量 父类 实例方法 base() 子类 重写的实例方法 test() ------------------------------- 1024 父类 实例方法 base() 子类 重写的实例方法 test() --------------------------------- 1024 子类A 实例方法 test()
|
从上面的运行结果中可以看出,
- 当父类引用指向
SubClass
这个子类时,调用的test
方法是子类SubClass
重写的test
方法,
- 当父类引用指向
A
这个子类时,调用的test
方法是子类A
重写的test
方法,
但是父类引用调用的实例变量
一直都是父类中定义的实例变量,
默认访问编译时类型中定义的成员变量
通过引用变量来访问实例变量时,总是访问编译时类型中定义的成员变量。