java多态 重写(override)的调用优先级

常规的说法是这样的:

在调用一个方法时,先从本类中查找看是否有对应的方法,如果没有再到父类中查看,看是否从父类继承来。否则就要对参数进行转型,转成父类之后看是否有对应的方法。总的来说,方法调用的优先级为:

this.func(this)
super.func(this)
this.func(super)
super.func(super)

先验证一下二级继承是否成立:

A
|
B

假如调用这样的语句

        A a = new A();
        B b = new B();
        b.fun(b);

检查的次序是这样的?
①、B中是否有方法fun(B b)?
②、A中是否有方法fun(B b)?
③、B 中是否有方法fun(A a)?
④、A 中是否有方法fun(A a)?

下面依次检验:

(一) ①>②?

class A{
    public void fun(B b){
        System.out.println("A.fun(B)");
    }
}
class B extends A{
    public void fun(B b){
        System.out.println("B.fun(B)");
    }
}
        A a = new A();
        B b = new B();
        b.fun(b);//B.fun(B)

符合预测

(二) ②>③?

class A{
    public void fun(B b){
        System.out.println("A.fun(B)");
    }
}
class B extends A{
    public void fun(A a){
        System.out.println("B.fun(A)");
    }
}

public class OverrideTest {
    public static void main(String []args){
        A a = new A();
        B b = new B();
        b.fun(b);//A.fun(B)
    }
}

符合预测

(三) ③>④?

class A{
    public void fun(A a){
        System.out.println("A.fun(A)");
    }
}
class B extends A{
    public void fun(A a){
        System.out.println("B.fun(A)");
    }
}

public class OverrideTest {
    public static void main(String []args){
        A a = new A();
        B b = new B();
        b.fun(b);//B.fun(A)
    }
}

但是,以上说的是二级继承,但是在多级继承中又是怎样的情况呢?

多级继承

A
|
B
|
C
|
D
        D d = new D();
        d.fun(d);

先说结论:优先级是:

d.fun(( d )
c.fun( d )
b.fun( d )
a.fun( d )
d.fun( c )
c.fun( c )
b.fun( c )
a.fun( c )
d.fun( b )
c.fun( b )
b.fun( b )
a.fun( b )
d.fun( a )
c.fun( a )
b.fun( a )
a.fun( a )

按照前面验证的规律,应该是先检验如下两处

  • D中是否有fun(D d)
  • C中是否有fun(D d)
    但是,假如以上两处检查不到,下一个应检查哪一条呢?是先检查D中的fun(C c),还是检查B中的fun(D d)?
class A{
}
class B extends A{
    public void fun(D d){
        System.out.println("B.fun(D)");
    }
}
class C extends B{

}

class D extends C{
    public void fun(C c){
        System.out.println("D.fun(C)");
    }
}

public class OverrideTest {
    public static void main(String []args){
        D d = new D();
        d.fun(d);//B.fun(D)
    }
}

检查完C中的fun(D d),就检查B中的fun(D d)
看到这里我忽然觉得:这和前面的:检查完D中的fun(D d)再检查C中的fun(D d)其实是一个意思。

是否可以这样理解:假如检查到C中的fun(D d),此时可以直接把c.fun(d)作为当前函数,再执行以下查找:
this.func(this)
super.func(this)
this.func(super)
super.func(super)

按照这个结论,检查完b.fun(d)就要检查a.fun(d)

class A{
    public void fun(D d){
        System.out.println("A.fun(D)");
    }
}
class B extends A{
}
class C extends B{

}

class D extends C{
    public void fun(C c){
        System.out.println("D.fun(C)");
    }
}

public class OverrideTest {
    public static void main(String []args){
        D d = new D();
        d.fun(d);//A.fun(D)
    }
}

证明了猜测

进而猜测d.fun(d)的检查顺序

d.fun(( d )
c.fun( d )
b.fun( d )
a.fun( d )
d.fun( c )
c.fun( c )
b.fun( c )
a.fun( c )
d.fun( b )
c.fun( b )
b.fun( b )
a.fun( b )
d.fun( a )
c.fun( a )
b.fun( a )
a.fun( a )

下面进行检查:
检查策略:先把所有的可能写上,那个方法被调用了,下一次就把这一个方法删掉,看下一次调用的是哪一个

class A{

    public void fun(A a){
        System.out.println("A.fun(A)");
    }
    public void fun(B b){
        System.out.println("A.fun(B)");
    }
    public void fun(C c){
        System.out.println("A.fun(C)");
    }
    public void fun(D d){
        System.out.println("A.fun(D)");
    }
}
class B extends A{
    public void fun(A a){
        System.out.println("B.fun(A)");
    }
    public void fun(B b){
        System.out.println("B.fun(B)");
    }
    public void fun(C c){
        System.out.println("B.fun(C)");
    }
    public void fun(D d){
        System.out.println("B.fun(D)");
    }

}
class C extends B{
    public void fun(A a){
        System.out.println("C.fun(A)");
    }
    public void fun(B b){
        System.out.println("C.fun(B)");
    }
    public void fun(C c){
        System.out.println("C.fun(C)");
    }
    public void fun(D d){
        System.out.println("C.fun(D)");
    }
}

class D extends C{
    public void fun(A a){
        System.out.println("D.fun(A)");
    }
    public void fun(B b){
        System.out.println("D.fun(B)");
    }
    public void fun(C c){
        System.out.println("D.fun(C)");
    }
    public void fun(D d){
        System.out.println("D.fun(D)");
    }
}

public class OverrideTest {
    public static void main(String []args){
        D d = new D();
        d.fun(d);
    }
}

结果证明了猜想

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值