向上转型之后的方法调用问题

假设定义了class A;
再在定义class B extends A;
我们可以这样定义一个对象:A a = new B();
栈中的引用变量是A,堆中的实例变量是B。
将子类的实例,赋值给父类的引用。就是向上转型。
向上转型,在运行时,会遗忘子类对象中与父类对象中不同的方法。也会覆盖与父类中相同的方法–重写。(方法名,参数都相同)
所以a2,可以调用的方法就是,A中有的,但是B中没有的方法,和B中的重写A的方法。
java 的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法, 但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。

实例:

public class A {

    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }

    public String show(B obj) {
        return ("A and B");
    }

}
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 C() {
        // TODO Auto-generated constructor stub
    }

}
public class D extends B{

    public D() {
        // TODO Auto-generated constructor stub
    }

}
        A aa1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        System.out.println(aa1.show(aa1));// A and A
        System.out.println(aa1.show(a2));// A and A
        System.out.println(aa1.show(b)); // A and A
        System.out.println(aa1.show(c)); // A and A
        System.out.println(aa1.show(d)); // A and D
        System.out.println("--------------");
        System.out.println(a2.show(aa1));// B and A  //使用class B 中的方法show(A obj)
        System.out.println(a2.show(a2));// B and A  //使用class B 中的方法show(A obj)
        System.out.println(a2.show(b)); // B and B  //使用class B 中的方法show(B obj)
        System.out.println(a2.show(c)); // B and B  //使用class B 中的方法show(B obj)
        System.out.println(a2.show(d)); // A and D  //使用class A 中的方法show(D obj)
        System.out.println("--------------");
        System.out.println(b.show(aa1));// B and A
        System.out.println(b.show(a2));// B and A
        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

    }

结果:
这里写图片描述

这里是比较好理解的,但是我们把改一下class A,将其改为:

public class A {

    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }

//  public String show(B obj) {
//      return ("A and B");
//  }

}

也就是在class A中不重载show(B obj)方法,其余不变,执行后的结果图:
这里写图片描述

发现只有

        System.out.println(a2.show(b)); //修改之前B and B 之后 B and A
        System.out.println(a2.show(c)); //修改之前B and B 之后 B and A

这两句的输出发生了改变,根据文章开头的叙述不难理解,由于修改过的class A中并没有show(B obj)方法,所以当我们向上转型后,class B中重载的show(B obj)被遗忘了,class B中重写的方法被保留,也就是说,此时class B中的内容相当于:

public class B extends A {

    public String show(A obj) {//重写了父类中的方法
        return ("B and A");
    }

    public String show(D obj) {//从父类继承
        return ("A and D");
    }
}
  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值