一,为了理解多态,我们先给出一个示例
代码示例:(打印多种图形)
class Shape{ 定义一个图形类作为父类
public void draw(){
//啥都不用干
}
}
class Cycle extends Shape{
@Override //声明重写父类中的方法
public void draw(){
System.out.println("⚪");
}
}
class Rect extends Shape {
@Override
public void draw(){
System.out.println("口");
}
}
class Flower extends Shape {
@Override
public void draw(){
System.out.println("♣");
}
}
//分割线//
public class Test1 {
public static void main(String[] args) {
Shape shape1 = new Cycle(); //生成三个实例对象
Shape shape2 = new Rect();
Shape shape3 = new Flower();
drawMap(shape1); //调用drawMap方法
drawMap(shape2);
drawMap(shape3);
}
public static void drawMap( Shape shape){ //用参数类型为父类
shape.draw();
}
}
运行结果:
观察总结:
在这个代码中, 分割线上方的代码是 类的实现者 编写的,分割线下方的代码是 类的调用者 编写的。当类的调用者在编写 drawMap 这个方法的时候,参数类型为 Shape (父类),此时在该方法内部并不知道,也不关注当 前的 shape 引用指向的是哪个类型(哪个子类)的实例.。此时 shape 这个引用调用 draw 方法可能会有多种不同的表现 (和 shape 对应的实例相关), 这种行为就称为 多态。
多态顾名思义, 就是 "一个引用, 能表现出多种不同形态"
二,使用多态的好处
1) 类调用者对类的使用成本进一步降低
- 封装是让类的调用者不需要知道类的实现细节。
- 多态能让类的调用者连这个类的类型是什么都不必知道,只需要知道这个对象具有某个方法即可。
因此, 多态可以理解成是封装的更进一步, 让类调用者对类的使用成本进一步降低。
2) 能够降低代码的 “圈复杂度”, 避免使用大量的 if - else
例如我们现在需要打印的不是一个形状了, 而是多个形状. 如果不基于多态, 实现代码如下:
public static void drawShapes() {
Rect rect = new Rect();
Cycle cycle = new Cycle();
Flower flower = new Flower();
String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};
for (String shape : shapes) {
if (shape.equals("cycle")) {
cycle.draw();
} else if (shape.equals("rect")) {
rect.draw();
} else if (shape.equals("flower")) {
flower.draw();
}
}
}
如果使用使用多态, 则不必写这么多的 if - else 分支语句, 代码更简单
public static void drawShapes() {
// 我们创建了一个 Shape 对象的数组.//
Shape[] shapes = {new Cycle(), new Rect(), new Cycle(),new Rect(), new Flower()};
for (Shape shape : shapes) {
shape.draw();
}
}
- 什么叫圈复杂度?
圈复杂度是一种描述一段代码复杂程度的方式. 一段代码如果平铺直叙, 那么就比较简单容易理解. 而如果有很 多的条件分支或者循环语句, 就认为理解起来更复杂. 因此我们可以简单粗暴的计算一段代码中条件语句和循环语句出现的个数, 这个个数就称为 “圈复杂度”. 如果一 个方法的圈复杂度太高, 就需要考虑重构。
3) 可扩展能力更强
class Triangle extends Shape {
@Override
public void draw() {
System.out.println("△");
}
}
对于类的调用者来说(drawShapes方法), 只要创建一个新类的实例就可以了, 改动成本很低. 而对于不用多态的情况, 就要把 drawShapes 中的 if - else 进行一定的修改, 改动成本更高.