2016-09-22 37 views
1
class A { 
    public void display(){ 
     System.out.println("From Class A"); 
    } 
} 

class B extends A { 
    public void display() { 
     System.out.println("From Class B"); 
    } 
} 

public class Test { 
    public static void main(Strings[] args){ 

     A a = new A(); 
     A b = new B() 
     a.display(); 
     b.display(); 
    } 
} 

輸出運行時多態性

From Class A  
From Class B 

現在,我得到的輸出如預期。 但我想知道爲什麼我使用A b = new B(),當我可以通過使用 B b = new B()實現同樣的事情。
使用以前技術的優勢在哪裏,何時對我有益?

+4

查看http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface - 不是你問的問題,但你應該找到答案的啓發。 –

+0

另請參閱此討論:[瞭解「編程到接口」](http://programmers.stackexchange.com/questions/232359/understanding-programming-to-an-interface)。 – DimaSan

回答

1

讓我們來看一個例子。我們都知道鳥可以飛,但也有一些例外。我們從他們的行爲知道,所以讓我們來模擬這個。

一般來說,鳥會飛,所以:

class Bird { 
    void fly() { 
     System.out.println("I can fly"); 
    } 
} 

class Eagle extends Bird { 
     void fly() { 
     System.out.println("I can fly very high"); 
    } 
} 

我們都知道,鴨子不能飛,但我們不說所有的鳥。我們在運行時說,一隻特定的鳥是否可以飛,取決於鳥。

class Duck extends Bird { 
     void fly() { 
     System.out.println("I can walk or swim only"); 
    } 
} 

class FlightDemo { 
     public static void main(String[] args) { 
     Bird bird = new Bird(); 
     bird.fly(); // output: I can fly 

     Bird eagle = new Eagle(); 
     eagle.fly(); // output: I can fly very high 

     Bird duck = new Duck(); 
     duck.fly(); // output: I can walk or swim only 
     } 
} 

你看到在運行時它決定鴨子不能飛。你可以覆蓋它的飛行行爲,它會走路或游泳。我們看到鴨子是鳥,它不能飛,所以我們已經超越了它的行爲,而鴨子仍然是鳥,它可以散步或游泳。

+0

Irfan @寫在這裏有什麼不對: 鴨鴨=新鴨(); duck.fly(); 我不會達到相同的功能。 –

+0

沒有什麼錯,但那不是多態。 Bird在運行時決定應該分配哪種行爲,一隻鴨子還是一隻鷹或者只是一隻鳥。 – iM71

1

在你的例子中,你選擇哪種方式並不重要。你的例子並沒有顯示多態的力量。

讓我們看看多態性的一個簡單的例子:

enter image description here

interface Shape{ 
    void draw(); 
} 

class Rectangle implements Shape{ 
    public void draw(){ 
     System.out.println("Drawing Rectangle."); 
    } 
} 

class Triangle implements Shape{ 
    public void draw(){ 
     System.out.println("Drawing Triangle."); 
    } 
} 

class Circle implements Shape{ 
    public void draw(){ 
     System.out.println("Drawing Circle."); 
    } 
} 

RectangleTriangleCircle只是實現自己draw函數的定義。

現在,假設您必須在您的Main類中實施drawAllShapes方法,該方法需要一堆形狀並將它們全部打印出來。但沒有多態性,這可能是忙碌的,因爲可能有不同類型的形狀。現在,這裏出現了多態性來拯救我們。

class RandomShapeFactory{ 
    public static Shape createRandomShape(){ 
     Shape randomShape; 

     Random random = new Random(); 
     int randomNo = random.nextInt() % 3 + 1; 
     if (randomNo == 1){ 
      randomShape = new Rectangle(); 
     } 
     else if (randomNo == 2){ 
      randomShape = new Triangle(); 
     } 
     else{ 
      randomShape = new Circle(); 
     } 
     return randomShape; 
    } 
} 

class Main{ 
    public static void main(String[] args){ 
     Shape[] shapes = new Shape[10]; 
     for (int i = 0; i < shapes.length; i++){ 
      shapes[i] = RandomShapeFactory.createRandomShape(); 
     } 
     drawAllShapes(shapes); 
    } 

    public static void drawAllShapes(Shape[] shapes){ 
     for (int i = 0; i < shapes.length; i++){ 
      shapes[i].draw(); 
     } 
    } 
} 

drawAllShapes此實現不必知道Shape在指數i是否是CircleTriangle或者是什麼,它是取其Shape,它只是要求其執行draw方法。

main方法具有所有隨機形狀,並且當傳遞給方法drawAllShapes時,它們的相關實現將被調用。

這種實現方法也跟在Open/Closed Principle之後,如果你希望將來可以在層次結構中添加更多形狀,drawAllShapes方法不必知道新形狀,只需添加新類並實現Shape接口和drawAllShapes也將使用這些形狀。

請參閱上述示例中的操作here

+0

您的回答更多地是針對軟件設計原則和模式,而不是運行時多態性的基本原理。 – Kahn

+0

我想,問題是,爲什麼要使用基類引用,並調用運行時多態的原則,而不是使用實際類本身的引用。所以我試圖用一個例子來展示多態的力量。 –