我对java继承的理解
2015-06-19 18:37
393 查看
关于java继承和多态的文章已经很多了,如果你对java的继承和多态已经有很好的理解,请绕过本变文章,
如果你对java的继承和多态不是很理解,还在找寻这方面的东西,那这篇文章可能对你有所帮助。
首先声明:
java里面轮子已经很多了,我不想在发明轮子,
但是这里也不是对轮子的照搬描述,
这里是我个人对java继承和多态的理解,
强调:本文着重说明的是继承,多态可能会涉及一些,不过这些都是为了辅助继承的理解的。
罗嗦了那么多,现在开始:
java的三大特性,封装、继承、多态。这里介绍继承。
继承:
“继承”是面向对象软件技术当中的一个概念。如果一个类A继承自另一个类B,就把这个A称为"B的子类",而把B称为"A的父类"。继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能[这段话来自互联网,如果有版权问题,请联系处理]
这里面有一个重要的表述:继承可以使得子类具有父类的各种属性和方法,
对很神奇的功能,继承可以实现代码的复用,也就是说,子烈可以直接使用父类的方法,【这里哪些方法能在子类中使用那些不能使用不作讨论】
多态:
多态是又一个重要的基本概念,继承是多态得以实现的基础。从字面上理解,多态就是一种类型表现出多种状态。比如说子类添加了一个方法或者属性之后,会成为一个新的类,这个类和其他子类不一眼,和父类也不一样,但是同属于一个父类型,都可以转化为父类型。而不同的子类就可以称为是多态
说了那么多,你的理解的? 恩 莫急先看一个问题:
这是前几天遇到的一个问题,具体原题目是什么记不太清楚,不过大致就是下面的样子:
package com.hung.test; public class T { public static void main(String[] args) { A1 a1 =new A2(); String s = new String(""); Object s1 = ""; double s2 = 12.1; a1.t1(s); a1.t1(s1); a1.t1(s2); } } class A1 { protected void t1(Object obj) { System.out.println("A1"); } public void t1(String obj) { System.out.println("A1-str"); } } class A2 extends A1 { public void t1(String obj) { System.out.println("A2-str"); } public void t1(Object obj) { System.out.println("A2-obj"); } public void t1(double obj) { System.out.println("A2-double"); } }
考一下你:执行结果会是什么?
好吧 看结果:
A2-str A2-obj A2-obj
是不是和你想的不一样? 如果一样那下面的内容你可以不看了。
那么再看下面一段代码 :
package com.hung.test; public class T { public static void main(String[] args) { A1 a1 =new A2(); System.out.println(a1.getClass().getName()); String s = new String(""); Object s1 = ""; double s2 = 12.1; a1.t1(s); a1.t1(s1); a1.t1(s2); A2 a2 =new A2(); a2.t1(s); a2.t1(s1); a2.t1(s2); } } class A1{ protected void t1(Object obj){ System.out.println("A1"); } public void t1(String obj){ System.out.println("A1-str"); } } class A2 extends A1{ public void t1(String obj){ System.out.println("A2-str"); } public void t1(Object obj){ System.out.println("A2-obj"); } public void t1(double obj){ System.out.println("A2-double"); } }
执行结果会是什么呢 ?
好吧,看下结果:
com.hung.test.A2
A2-str A2-obj A2-objA2-str
A2-obj
A2-double
好了,问题出来了?
为什么两次
A1 a1 =new A2(); a1.t1(s); a1.t1(s1); a1.t1(s2);
与
A2 a2 =new A2(); a2.t1(s); a2.t1(s1); a2.t1(s2);
的执行结果不一样:
看下代码已有一个地方不一样
就是变量声明的类型
也就是说
A1 a1 =new A2();
与
A2 a2 =new A2();
的问题。
他们俩不同,一个是父类,一个是子类。
我勒个去 都是
new A2();
对象,为什么执行出来就不一样呢,
下面会介绍执行结果为什么会这样。
引用另外一个概念:
绑定:
将一个方法调用同这个方法所属的主体(也就是对象或类)关联起来叫做绑定,
前期绑定:在程序运行之前进行绑定,由编译器和连接程序实现,又叫做静态绑定。比如static方法和final方法,注意,这里也包括private方法,因为它是隐式final的。
后期绑定:在运行时根据对象的类型进行绑定,由方法调用机制实现,因此又叫做动态绑定,或者运行时绑定。除了前期绑定外的所有方法都属于后期绑定。
好 现在解释上面的原因:
声明变量:
A1 a1 =new A2();
其实a1是一个A1对象的引用,只不过有点特殊的地方时,a1指向的是A2的对象,这会有什么影响呢?
编译器并没有那么聪明,在编译期间,会认为我要执行的是A1的t1()方法,当我们开始运行期执行方法的时候起初还是认为要执行A1的方法,但是执行方法的时候中间多了一个过程,见动态绑定,他会把要执行的方法和具体的所属对象进行关联,也就是是说,当运行期执行代码的时候,才会找到原来我执行的是A2的t1()方法,但是A2中有几个t1,他会找到哪个呢,我的理解是他会根据方法签名来确认到底执行哪个方法,【方法前面就是方法的名称,参数,参数类型,个数,修饰符,等。】
所以如果a1执行t1传递过来的参数是object的,那么会执行a2的参数为类型为object的t1方法,
同理,如果a1执行t1参数为String的,那么会执行a2的参数类型为String的t1方法。
解释完毕:
欢迎拍砖。
其中文件中引用了其他人博客的内容,地址如下:
http://zangweiren.blog.51cto.com/412366/94387
多谢 、
相关文章推荐
- java对象的复制
- c#委托与java处理
- java对象的复制
- java操作字符,java全角转半角
- myeclipse 10 发布了 付下载地址
- unable to locate configuration files of the name struts-plugin.xml提示信息的解决办法
- javaeye被csdn收购了
- struts2中日期标签的<sx:datatimepicker>的使用
- Java String.Format() 方法及参数说明
- Java学习日记之反射
- Java读写CSV格式文件(opencsv)
- java的异常处理机制
- Java 文件上传 JQ 文件上传
- 重踏学习Java路上_Day05(java 基础下,方法与数组)
- java多线程的知识点总结
- java开发知识体系
- myeclipse2015 相关插件安装
- java 日期工具
- Classpath 设置了但是找不到包?
- java读取properties配置文件