面向对象的三大特性(封装、继承、多态)之一
封装和继承几乎都是为多态而准备的
必要条件
1. 要有继承;
2. 要有重写;
3. 父类引用指向子类对象。
好处
1. 可替换性(继承保证)
2. 可扩展性(由多态保证)
3. 消除类型之间的耦合关系
弊端
不能使用子类的特有功能。
要想使用子类的特有功能:
1. 创建子类对象调用方法即可(可以,但是很多时候不合理。而且,太占内存了)
2. 把父类的引用强制转换为子类的引用。(向下转型)
向上转型:
Fu f = new Zi();
向下转型:
Zi z = (Zi)f;
访问特点
1. 成员变量
编译看左边,运行看左边。
2. 构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
3. 成员方法
编译看左边,运行看右边。(由于成员方法存在方法重写,所以它运行看右边)
4. 静态方法
编译看左边,运行看左边。(静态和类相关,算不上重写,所以,访问还是左边的)
优先级
由高到低依次为:
1. this.show(O)
2. super.show(O)
3. this.show((super)O)
4. super.show((super)O)
例子:
public class A{
public String show(D obj){
return ("A and D");
}
public String show(A obj){
return ("A and A");
}
}
public class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
}
}
public class C extends B{}
public class D extends B{}
// 测试
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println(a1.show(b)); // A and A
System.out.println(a1.show(c)); // A and A
System.out.println(a1.show(d)); // A and D
System.out.println(a2.show(b)); // B and A
System.out.println(a2.show(c)); // B and A
System.out.println(a2.show(d)); // A and D
System.out.println(b.show(b)); // B and B
System.out.println(b.show(c)); // B and B
System.out.println(b.show(d)); // A and D
分析:
对照优先级来看,首先我们分析a2.show(c),a2是A类型的引用变量,所以this就代表了A,它在A类中找发现没有找到,于是到A的超类中找(super),由于A没有超类(Object除外),所以优先级跳到第三级,也就是this.show((super)O),C的超类有B、A,所以(super)O为B、A,this同样是A,这里在A中找到了show(A obj),同时由于a2是B类的一个引用且B类重写了show(A obj),因此最终会调用子类B类的show(A obj)方法,结果也就是B and A。其他依次类推即可