在学java面向对象设计这一章时,对于java的多态总是不理解。前前后后用了大概一周的时间,才大概地对多态有了一点了解。写一篇博客记录一下自己的一些看法。
多态的定义
书上对多态的定义是:“多态泛指能够创建多于一种形式的变量,方法和对象的能力”。至少我对这句话没有理解。。。后来看了后面的具体内容才有了一点明白。下面我按照自己的理解描述一下:
对于方法而言的多态
多于一种形式的方法就是指,该方法可以接受不同的形式的参数,并且对不同形式的参数有不同的处理手段。这里的不同形式的参数,包括参数的类型和参数的数量。就类型而言,书上给的例子,比如java.lang.Math中的max()方法:
public static double Math.max(double a, double b)
public static float Math.max(float a, float b)
public static int Math.max(int a, int b)
就参数的数量而言,比如:
public String[] split(String regex)
public String[] split(String regex, int limit)
老实说,平时使用max方法时也没有细想max方法居然可以处理不同类型的参数,而这种特性在许多方法中都有,这就说明max方法其实是有不同的形式的,这种特性就是多态。而这种特性的实现使用的方法就叫做方法重载。
在面向对象的语言中,如果参数是引用类型的变量,就会涉及到父类子类的问题。如果参数类型是父类类型的方法,可以接受子类类型的参数变量并在处理上有某些变化,这也是方法的多态。这种多态,可以看出是把子类当作父类看待,所以又叫向上转型。
多态的实际实现
多态常常被描述为“对外一个接口,对内多种实现”,意思就是对于具有多态性的方法而言,不管参数形式如何,对方法调用时的方法名称是一样的。而实际上在类内部实现方法时是针对不同的参数形式有不同的实现的。下面会举学习多态过程中遇到的例子来具体说明一下。
多态性体现的例子
书上将多态分为编译时的多态和运行时的多态,这是因为对于方法重载而言,多态性的实现,即方法的多次声名是在编译时就实现的。而对于向上转型而言,多态性涉及动态绑定,这就是因为向上转型时,可能出现父类类型的变量实际是子类类型变量的引用,而这在编译阶段不能被编译器察觉,因此会在运行时根据对象的的类型进行绑定。
下面是一个方法重载的例子:
public class TestOverloading2 {
public static void main(String[] args) {
Student stu = new Student();
System.out.println(stu.getName()+" , "+stu.getID());
}
}
class Student{
private String name;
private String id;
public Student(String nm, String id) {
this.name = nm;
this.id = id;
}
public Student(String nm) {
this(nm,"00000000");
}
public Student()
{
this("unknown");
}
public String getName() {
return name;
}
public String getID() {
return id;
}
}
运行结果为:
unknown , 00000000
可以看出多态的实际实现是方法的多次声名,且每次声名中参数形式的不同。
下面是一个向上转型的例子,来源于《Java实用程序设计》西安电子科技大学,孙聪版。
public class homework9 {
public static void main(String[] args) {
Cycle cc = new Cycle();
Cycle[] x = {new Unicycle(),new Bicycle(),new Tricycle()};
for(int i=0;i<x.length;i++) {
cc.ride(x[i]);
}
}
}
class Cycle{
public void ride(Cycle c) {
System.out.println("ride the cycle");
c.wheel();
}
public void wheel() {
System.out.println("the count of wheels is 4");
}
}
class Unicycle extends Cycle{
public void wheel() {
System.out.println("the count of wheels is 1");
}
public void balance() {
System.out.println("unicycle hard to balance");
}
}
class Bicycle extends Cycle{
public void wheel() {
System.out.println("the count of wheels is 2");
}
public void balance() {
System.out.println("bicycle hard to balance");
}
}
class Tricycle extends Cycle{
public void wheel() {
System.out.println("the count of wheels is 3");
}
}