您的位置:首页 > 编程语言 > Java开发

java中多态的经典问题分析

2016-03-26 20:14 295 查看

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编译时候首先编译器会根据调用关系,编译生成相对字节码文件,然后根据创建对象的实际类型去调用相对应的子类或者父类的方法。

第一条语句,A类没有子类,执行第一条语句时候会去A中适应查找所以 输出为 A and A

跟第一条一样。

当调用show(D) 时候,由于A类中有声明显示D的方法,所以直接调用相对的方法,而不会根据前两条一样去适应。也就是方法参数的所对应方法的选择主要看静态类型,也就是传入参数的声明类型。

第四条语句,首先我们查左边,发现a2是A类型,所以会去A方法中查找,这时候我们找到适应的方法,也就是show(A obj) 但运行时候我们发现a2是 B类型所以会调用B中的相对应重写的方法,所以输出为 B and A

原理同第四条。

由于B中没有重写 show(D obj)方法所以会调用A中的方法做处理,因此会输出 A and D

直接调用自己方法

显而易见

跟前面分析一样

概括的说重载主要看传入参数的左边类型,重写调用时候如果存在重载,则首先根据左边类型看参数调用对应方法,然后再根据调用者的实际类型处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: