转载:https://www.cnblogs.com/chenssy/p/3372798.html
实现条件
- **继承:**在多态中必须存在有继承关系的子类和父类。
- **重写:**子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
- **向上转型:**在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
实现形式
- 继承
基于继承的实现机制主要表现在父类和继承该父类的一个或多个子类对某些方法的重写,多个子类对同一方法的重写可以表现出不同的行为。
public class InheritWine {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public InheritWine(){
}
public String drink(){
return "喝的酒是: "+ getName();
}
@Override
public String toString() {
return null;
}
public static class Jnc extends InheritWine{
public Jnc(){
setName("Jnc");
}
/**
* 重写父类的方法,实现多态
*/
@Override
public String drink() {
return "喝的酒是: "+ getName();
}
/**
* 重写toString()
*/
@Override
public String toString(){
return "Wine : " + getName();
}
}
public static class Jgj extends InheritWine{
public Jgj(){
setName("Jgj");
}
/**
* 重写父类的方法,实现多态
*/
@Override
public String drink() {
return "喝的酒是: "+ getName();
}
/**
* 重写toString()
*/
@Override
public String toString(){
return "Wine : " + getName();
}
}
public static class Test{
public static void main(String[] args) {
InheritWine[] inheritWines = new InheritWine[2];
Jnc jnc = new Jnc();
Jgj jgj = new Jgj();
//父类引用子类对象
inheritWines[0] =jnc;
inheritWines[1] = jgj;
for(int i=0;i<2;i++){
System.out.println(inheritWines[i].toString()+"----"+inheritWines[i].drink());
}
}
}
}
结果:
Wine : Jnc----喝的酒是: Jnc
Wine : Jgj----喝的酒是: Jgj
- 接口
在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。
public class InterfaceA {
public String show(D obj){
return "A and D";
}
public String show(InterfaceA obj){
return "A and A";
}
public static class B extends InterfaceA {
public String show(B obj) {
return "B and B";
}
@Override
public String show(InterfaceA obj){
return "B and A";
}
}
public static class C extends B{
}
public static class D extends B{
}
public static class Test {
public static void main(String[] args) {
InterfaceA a1 = new InterfaceA();
InterfaceA a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println("1--" + a1.show(b));
System.out.println("2--" + a1.show(c));
System.out.println("3--" + a1.show(d));
System.out.println("4--" + a2.show(b));
System.out.println("5--" + a2.show(c));
System.out.println("6--" + a2.show(d));
System.out.println("7--" + b.show(b));
System.out.println("8--" + b.show(c));
System.out.println("9--" + b.show(d));
}
}
}
结果:
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D
分析:
在继承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
- a1.show(b),------a1是A类型的引用变量,所以this就代表了A,在A中找到了show(B
obj),因此return “A and A”; - 同上;
- a1.show(D),------a1是A类型的引用变量,所以this就代表了A,在A中找到了show(D obj),因此return “A and D”;
- a2.show(b),------a1是A类型的引用变量,所以this就代表了A,a2.show(b),它在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)方法,因此return “B and A”; - 同上;
- a2.show(d),------a2是A类型的引用变量,所以this就代表了A,在A中找到了show(D obj),因此return “A and D”;
- b.show(b),------b是B类型的引用变量,所以this就代表了B,在B中找到了show(B obj),因此return “B and B”;
- 同上;
- b.show(d),------b是B类型的引用变量,所以this就代表了B,b.show(d)它在B类中没有找到,于是到B的超类(父类)中找(super),B的父类是A,所以(super).show(O)为A.show(O),在A类中找到show(D obj),因此return “A and D”;
虽然从坑中爬出了,但是脑壳晕