Java-多态、方法重载
2015-07-15 15:45
786 查看
什么是多态、重载
1. 多态
对多态现象的理解
多态是面向对象的一个重要特征。关于定义性的概念,相信网上有很多资料,不再多说。这里说说我自己的理解。多态是指在运行期间,调用某个类对象的方法会有不同的行为。举个最普遍的例子来说:基类:Shape
[code]class Shape{ public void draw(); public void clear(); }
子类: Circle 、Rectangle
[code]class Circle extends Shape{ public void draw(); //画一个圆 public void clear(); } class Rectangle extends Shape{ public void draw(); //画一个长方形 public void clear(); }
如果我声明一个
Shape类的引用,然后初始化,最后调用这个对象的
draw()方法:
[code]Shape mShape = null; mShape = init(); mShape.draw();
由于
Rectangle类的对象和
Circle类的对象都可以向上转换为
Shape的对象,所以当我调用
mShape.draw()方法后,可能会画一个圆,也有可能会画一个长方形,这完全取决于
init()方法返回的对象是什么。这种现象称为多态,而且这种现象在现实中是普遍存在的,例如对车来说,有汽车,电动车,车都有
行驶行为,对不同的车来说,会采取不同的实际行动来执行
行驶这个行为,这是多态在现实中的体现。
多态发生的时机
多态发生在运行期间,这是因为不到实际运行时,我们永远不知道init()方法返回的到底是哪个实际的对象,因此多态会推迟到运行期间发生。但是当方法是static或final修饰时,在编译期间便进行绑定。原因是final方法不允许重写,而static方法是跟类绑定的,与对象无关。
2.重载
很多人会将重载跟多态混淆,多态的发生必须要有继承、重写 , 而重载不一样,重载是指同一个方法名(只指的是名字),有多个不同的版本,例如我们要写一个add方法,如果是两个数字,返回求和后的字符串。如果是两个字符串,我们就将字符串联接起来。写成代码就是如下的样子:
[code]class Example{ public String addInt(int a , int b){ return (a + b) + ""; } public String addString(String a , String b){ StringBuilder temp = new StringBuilder(); temp.append(a); temp.append(b); return temp.toString(); } }
但是这样会有很多不同的方法,容易造成混淆。我们编写一个方法的多个不同版本,根据传入的参数不同,调用不同版本的方法。因此就有方法重载。
[code]class Example{ public String add(int a , int b){ return (a + b); } public String add(String a , String b){ StringBuilder temp = new StringBuilder(); temp.append(a); temp.append(b); return temp.toString(); } }
根据传入参数的不同,编译器会调用不同版本的方法。
重载发生的时机
由于方法调用的参数是编译期确定的,因此重载发生在编译期。重载时方法匹配的优先级
(引用自http://liujinpan75.iteye.com/blog/495562)根据调用的方法名,查找是否有定义好的同名方法,如果没有就会报错
比较形参和实参的数目是否相等,如果没有则会报错。如果有一个或多个方法符合条件,这些方法进入候选集
与候选集中的方法比较参数表,如果对应位置上的每个参数类型完全匹配,或者可以通过扩展转换相匹配,则该方法称为可行方法,并入可行集。若不存在可行方法,则会报错
在可行集中按照下面的原则选取最佳可行方法,若最佳可行方法为0 则会报错,否则最佳可行方法就是最终确定要调用的方法
获取的原则是
1. 若每一个参数都可以完全匹配,它就是最佳可行方法
2. 若某个方法的每一个参数都不比别的方法差,且至少有一个参数比别的方法好,它就是最佳可行方法,这里的差和好是指,完全匹配要比扩展转化好,不过同样是扩展转换,仍然存在好和差的问题,扩展转换有两条路径
byte-short-int-long-float-double
char-int-long-float-double
这两条路径中位于左边的类型都可以转换为右边的类型,不过源类型与目标类型的距离越近,则这种转化就越好。
3. 如果存在自动装箱和变长参数,则扩展转换的优先级大于自动装箱,自动装箱的优先级大于变长参数。
相关文章推荐
- How To create Netbeans Platform and add to netbeans IDE by netbean platform manager
- 关于eclipse的jar包问题
- Java_类和对象(完美总结)_转载_覆盖和隐藏的区别,覆盖就不能使用了,而隐藏提供全局方法名或者全局变量名还可以使用
- Java错误提示------println()错误
- 读配置文件可以保持顺序的 Java Properties 类
- 编写一个程序,将 d: \ java 目录下的所有.java 文件复制到d: \ jad 目录下,并 将原来文件的扩展名从.java 改为.jad
- 深入浅出 Java Concurrency (6): 锁机制 part 1
- java枚举类型enum的使用
- Java常见内存溢出异常分析(OutOfMemoryError)
- AOP Spring
- Springmvc JSON交互
- 【转】Java并发编程:Thread类的使用
- Java项目经验
- `java.lang.ClassNotFoundException: org.springframework.web.util.Log4jConfigListener`
- Spring MVC重定向
- Java opencv中sift的实现
- 【转】深入理解java异常处理机制
- Java深入 - logback的配置和使用
- Maven 项目在集成Eclipse环境报错
- 网易云课堂java进阶 编程题