多态是面向对象的一个重要特征。关于定义性的概念,相信网上有很多资料,不再多说。这里说说我自己的理解。多态是指在运行期间,调用某个类对象的方法会有不同的行为。举个最普遍的例子来说:
基类:Shape
class Shape{
public void draw();
public void clear();
}
子类: Circle 、Rectangle
class Circle extends Shape{
public void draw(); //画一个圆
public void clear();
}
class Rectangle extends Shape{
public void draw(); //画一个长方形
public void clear();
}
如果我声明一个Shape
类的引用,然后初始化,最后调用这个对象的draw()
方法:
Shape mShape = null;
mShape = init();
mShape.draw();
由于Rectangle
类的对象和Circle
类的对象都可以向上转换为Shape
的对象,所以当我调用mShape.draw()
方法后,可能会画一个圆,也有可能会画一个长方形,这完全取决于init()
方法返回的对象是什么。这种现象称为多态,而且这种现象在现实中是普遍存在的,例如对车来说,有汽车,电动车,车都有行驶
行为,对不同的车来说,会采取不同的实际行动来执行行驶
这个行为,这是多态在现实中的体现。
多态发生在运行期间,这是因为不到实际运行时,我们永远不知道init()
方法返回的到底是哪个实际的对象,因此多态会推迟到运行期间发生。但是当方法是static或final修饰时,在编译期间便进行绑定。原因是final方法不允许重写,而static方法是跟类绑定的,与对象无关。
很多人会将重载跟多态混淆,多态的发生必须要有继承、重写 , 而重载不一样,重载是指同一个方法名(只指的是名字),有多个不同的版本,例如我们要写一个add
方法,如果是两个数字,返回求和后的字符串。如果是两个字符串,我们就将字符串联接起来。写成代码就是如下的样子:
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();
}
}
但是这样会有很多不同的方法,容易造成混淆。我们编写一个方法的多个不同版本,根据传入的参数不同,调用不同版本的方法。因此就有方法重载。
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();
}
}
根据传入参数的不同,编译器会调用不同版本的方法。
由于方法调用的参数是编译期确定的,因此重载发生在编译期。
获取的原则是
1. 若每一个参数都可以完全匹配,它就是最佳可行方法
2. 若某个方法的每一个参数都不比别的方法差,且至少有一个参数比别的方法好,它就是最佳可行方法,这里的差和好是指,完全匹配要比扩展转化好,不过同样是扩展转换,仍然存在好和差的问题,扩展转换有两条路径
byte-short-int-long-float-double
char-int-long-float-double
这两条路径中位于左边的类型都可以转换为右边的类型,不过源类型与目标类型的距离越近,则这种转化就越好。
3. 如果存在自动装箱和变长参数,则扩展转换的优先级大于自动装箱,自动装箱的优先级大于变长参数。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/zjx409/article/details/46888917