1. 起因:看了java编程思想,突然发现java中的多态的向上转型还是很神奇的,为此做一下笔记,表示看过:
2. 先看图片:
3.再看代码:
public class Circleextends Shape{
public void erase(){ System.out.println("erase"); } public void draw(){ System.out.println("Circle 画图"); } public static void main(String[]args) {//主方法 Circle circle = new Circle() ; Triangle triangle = new Triangle() ; Square square = new Square(); doSomething(square); doSomething(circle); doSomething(triangle); } public static void doSomething(Shapeshape) { shape.draw(); shape.erase(); } }
class Shape{//基类 public void erase(){ System.out.println("erase"); } public void draw(){ System.out.println("shape 画图"); } }
class Square extends Shape{ public void erase(){ System.out.println("square....."); } public void draw(){ System.out.println("square 画图"); } }
class Triangle extends Shape{ public void erase(){ System.out.println("Triangle....."); } public void draw(){ System.out.println("triangle 画图"); } }
|
|
通过上面的代码可以看到,一共四个类,一个基类(Shape), 三个子类(Circle,Square,Triangle)
对doSomething()调用会自动地正确处理,而不管对象的确切类型。
这是一个令人感到惊奇的诀窍,看看下面这行代码:
doSomething(circle);
当circle传入到预期接收Shape的方法中,究竟会发生什么, 由于Circle可以被doSomething()看作是Shape,也就是说,doSomething()可以发送给Shape的任何消息(shape对象的任何方法),Circle都可以接收,那么,这么做是完全安全且合乎逻辑的。
一个面向对象程序肯定会在某处包含向上转型,因为这正是将自己从必须知道确切类型中解放出来的关键。让我们再看看doSomething()中的代码:
shape.erase();
shape.draw();
重点:注意这些代码并不是说“如果是Cricle,请这样做,如果是Square,请那样做……”。如果编写了那种检查Shape所有实际可能类型的代码,那么这段代码肯定是杂乱不堪的,而且在每次添加了Shape的新类型之后都要修改这段代码。这里所要表达的意思仅仅是“你是一个Shape,我知道你可以erase()和draw()你自己,那么去做吧,但是要注意细节的正确性。”