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
直接调用自己方法
显而易见
跟前面分析一样
概括的说重载主要看传入参数的左边类型,重写调用时候如果存在重载,则首先根据左边类型看参数调用对应方法,然后再根据调用者的实际类型处理。
相关文章推荐
- myeclipse安装svn插件并使用(本地link链接式安装插件-非侵入式安装)
- JAVA GC机制
- Spring-AOP
- 详解spring-MVC DispatcherServlet初始化
- java web图片显示到浏览器
- Myeclipse怎么导入工程项目
- java按照指定编码方式读取文件
- MyEclipse与Mysql数据库的连接
- 两个大数相乘JAVA版
- Java中关于继承与多态的一道选择题
- 20145236 《Java程序设计》第4周学习总结
- java事务学习笔记(三)--丑陋的案例
- Java小的细节方面的整理与归纳
- 20145227 《Java程序设计》第4周学习总结
- 使用Java面向对象程序操作Oralce数据库实现界面增,删,改,查
- Eclipse修改默认编码格式:工作空间,工程,文件,某类文件(如jar)
- 在java中使用和创建自定义的native方法
- java集合框架
- java集合框架
- Java中的枚举类