什么是多态
一般说道多态,也离不开封装与继承。按我的理解,Java中的封装,就是把一些属性与方法打包成一个类,用来描述一个对象的状态与动作。Java中的继承,则是通过继承一个通用类来得到一个一个更具体的类。两者都是能帮助我们更好地进行建模的代码格式。
理解多态的概念也离不开封装与继承。多态的字面意思就是多种形式、多种形态。例如,几何图形可以是圆、三角形、矩形或任意不规则的图形。为了将这种抽象的关系体现在Java上,我们可以先定义一个几何图形的通用类,再通过继承得到圆、三角形这些子类。在使用过程中,不必先定义某一个子类引用,在把一个子类实例传递给它,因为每个子类的实例都是父类的特殊化,因此总是可以将子类的实例传给需要父类型的参数,大大提升了编程的灵活性。
背景知识:封装、继承与方法重写
class Animal {
public void animalSound() {
System.out.println("The animal makes a sound");
}
}
class Pig extends Animal {
@Override
public void animalSound() {
System.out.println("The pig says: wee wee");
}
}
class Dog extends Animal {
@Override
public void animalSound() {
System.out.println("The dog says: bow wow");
}
}
知识点详述:多态的应用及类型转换
下面用父类型引用来指向子类型实例
class Animal {
public void animalSound() {
System.out.println("The animal makes a sound");
}
}
class Pig extends Animal {
public void animalSound() {
System.out.println("The pig says: wee wee");
}
public void display() {
System.out.println("Pig");
}
}
class Dog extends Animal {
public void animalSound() {
System.out.println("The dog says: bow wow");
}
}
class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // Create a Animal object
Animal myPig = new Pig(); // Create a Pig object
Animal myDog = new Dog(); // Create a Dog object
myAnimal.animalSound();
myPig.animalSound();
myDog.animalSound();
//myPig.display(); 编译错误
Pig p = (Pig)myPig;
p.display();
}
}
Java中,总是可以将一个子类的实例转换为一个父类的变量,称为向上转换(upcasting)。但要注意转换后的父类引用不能调用子类有而自身没有的方法,像上面的myPig.display()就会出现编译错误。为了解决这一问题,要用到向下转换(downcasting),也就是把父类实例转换为子类变量。这时必须用转换标记“(子类名)”进行显示转换,向编译器表明你的意图,于是就可以调用子类的特殊方法,结果如下
The animal makes a sound
The pig says: wee wee
The dog says: bow wow
Pig
使用场景
下面介绍一个多态的应用场景。假设有三次考试,每次的分数制都不一样,第一次采用五级计分制第二次采用两级计分制,第三次采用五级计分制。若要显示每次考试的成绩,如果采用一般的思路,要对三次考试分别建模,并编写不同的getScore方法,再分别调用。而在Java中,可以让这三次考试都继承自一个通用类(GradeActivity),并分别重写各自的getScore方法,最后用循环依此调用getScore方法,即使test中有上百个实例,每个实例的计分方法都不同,也可以用循环来实现。
public static void main(String[] args) {
GradedActivity[] tests = new GradedActivity[3];
// 第一次考试采用五级计分制,考了75
tests[0] = new GradedActivity();
tests[0].setScore(75);
// 第二次考试采用二级计分制(P或者F)。总共20题,每题分值相同,考生答错5题。
// 通过的最低分数线是60分
tests[1] = new PassFailExam(20, 5, 60);
// 第三次是期末考试也采用五级计分制. 总共50题,每题分值相同,考试答错7题
tests[2] = new FinalExam(50, 7);
// 显示每次考试的分数和等级
for(int i=0; i<tests.length; i++){
showValue(tests[i]);
}
}
public static void showValue(GradedActivity exam){
System.out.println("Score: " + exam.getScore()+ "\t" +
"Grade: " + exam.getGrade());
}
小结
与其说多态是一种代码格式,不如说多态是一种写代码的技巧。能否利用好多态的机制取决于对需求的理解,如果能利用好其特性,能在实际的应用场景中减轻工作量,提升程序的灵活性。