一个类实例轻松了解多态

先说重点,不理解的就先大概看一遍过,把之后的例子理解了,这些自然也懂了

结论1:当超(父)类对象的引用变量 引用子类对象时,被引用对象的类型决定了调用谁的 成员方法,这个被调用的方法必须是在超类中定义过的,即被子类重载或者重写的方法。

判断题:在java的多态调用中,new的是哪一个类就是调用的哪个类的方法。( X )

如果是重写进行的多态调用,运用的就是动态单分配,是根据new的类型确定对象,从而确定调用的方法。说法正确。

如果是重载进行的多态调用,运用的就是静态多分派,即根据静态类型确定对象,因此不是根据new的类型确定调用的方法。说法错误。

结论2:向上转型的父类类型的引用可以调用父类中定义的所有属性和方法,对于只存在子类,父类没有的方法和属性,它就无法调用了。比如子类有属性A,方法B,而父类里没有,就是子类没有重写父类的方法,重载也不行,那父类类型的引用就无法调用属性A和方法B了。而如果子类重写了父类里的方法,那么在调用同名方法的时候,必定是使用子类定义的方法,即动态连接、动态调用。即当子类重写父类的方法被调用时,只有对象继承链中的最末端子类的方法才会被调用

结论3:在继承链中对象方法的调用存在一个优先级

this.show(O)-->super.show(O)-->this.show((super)O)-->super.show((super)O)
this.show(O):方法调用,是先调用当前类引用对象(this)的show(O)方法

super.show(O):如果当前类引用对象没有show(O),就调用当前类的超类引用对象(super)的show(O)
this.show((super)O):如果还没有,就看这个形参O的超类都有什么,然后选择this == 超类的类
替代形参O,即this.show(this t)

super.show((super)O):再没有得到结果,就只能去this的超类里面找形参O的超类方法了,
理解了前三步,这个就可以意会了

 

好的,程序员不多bb,用代码说话:

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{
 
}
 
public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        
        System.out.println("1--" + a1.show(b));// A and A
        System.out.println("2--" + a1.show(c));// A and A
        System.out.println("3--" + a1.show(d));// A and D
        System.out.println("4--" + a2.show(b));// B and A
        System.out.println("5--" + a2.show(c));// B and A
        System.out.println("6--" + a2.show(d));// A and D
        System.out.println("7--" + b.show(b)); // B and B
        System.out.println("8--" + b.show(c)); // B and B
        System.out.println("9--" + b.show(d)); // A and D     
    }
}

现在我们来解释代码结果,先画出ABCD类的继承关系图:

解释a1.show(b)的结果1--A and A,注意a1是new A(),所以调用的是A的方法,看结论1,然后使用结论3:

this.show(O),A里面没有show(B b)这个方法,无法得到结果

super.show(O),A的超类是Object,排除这个之外再没有其他超类了,所以也不行

this.show((super)O),B的超类是A,则可以等价转换为this.show(this t),即A.show(A a),发现A里面有这个方法。所以结果就是A and A

同理得a1.show(c),而a1.show(d)结果不一样是因为A本身就有show(D obj)

 

接下来看a2.show(c),它的结果是B and A,使用结论3:

①this.show(O),A里面没有show(B b)这个方法,无法得到结果

②super.show(O),A的超类是Object,排除这个之外再没有其他超类了,所以也不行

③this.show((super)O),C的超类是A和B,而this又是A,所以可以等价替换为this.show(this t),即A.show(A a),但是由于子类B继承A,重写了show(A a),所以调用的是子类B的show(A a),这个不理解的看结论2。所以结果就是B and A

同理得到其他。

参考的文章链接:https://blog.csdn.net/chenssy/article/details/12786385

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值