java中多态的经典问题分析

Question

package demo;

/**
 * Created by zwj on 2016/3/26.
 */


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

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

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

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

class C extends B {

}

class D extends B {

}

public class ABCD {

    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(a1.show(b)); // 1:a  a
        System.out.println(a1.show(c)); //2:a a
        System.out.println(a1.show(d)); //3:a d
        System.out.println(a2.show(b)); //4:b a
        System.out.println(a2.show(c)); //5:b a
        System.out.println(a2.show(d)); //6:a d、
        System.out.println(b.show(b));//7:b b
        System.out.println(b.show(c)); //8:b b
        System.out.println(b.show(d)); //9:a d
    }
}


分析

首先我们要明白一个道理,对于java中的多态是编译看左边,运行看右边,方法在调用的时候会出现两种情况,一种是重载,另一种是子类重写。

重载

对重载来说,java在编译时候由编译器已经确定要调用的方法,也就是说编译器根据两个属性来做处理,首先是调用者,还有就是方法参数,通过这两个宗量就可以确定重载调用的方法,方法参数看传入的变量的静态类型,也就是声明类型,不是看其实际类型。

重写

对重写来说,java编译时候首先编译器会根据调用关系,编译生成相对字节码文件,然后根据创建对象的实际类型去调用相对应的子类或者父类的方法。

  1. 第一条语句,A类没有子类,执行第一条语句时候会去A中适应查找所以 输出为 A and A
  2. 跟第一条一样。
  3. 当调用show(D) 时候,由于A类中有声明显示D的方法,所以直接调用相对的方法,而不会根据前两条一样去适应。也就是方法参数的所对应方法的选择主要看静态类型,也就是传入参数的声明类型。
  4. 第四条语句,首先我们查左边,发现a2是A类型,所以会去A方法中查找,这时候我们找到适应的方法,也就是show(A obj) 但运行时候我们发现a2是 B类型所以会调用B中的相对应重写的方法,所以输出为 B and A
  5. 原理同第四条。
  6. 由于B中没有重写 show(D obj)方法所以会调用A中的方法做处理,因此会输出 A and D
  7. 直接调用自己方法
  8. 显而易见
  9. 跟前面分析一样
    概括的说重载主要看传入参数的左边类型,重写调用时候如果存在重载,则首先根据左边类型看参数调用对应方法,然后再根据调用者的实际类型处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值