<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ### [產生正確的行為](https://lingcoder.gitee.io/onjava8/#/book/09-Polymorphism?id=%e4%ba%a7%e7%94%9f%e6%ad%a3%e7%a1%ae%e7%9a%84%e8%a1%8c%e4%b8%ba) 一旦當你知道 Java 中所有方法都是通過后期綁定來實現多態時,就可以編寫只與基類打交道的代碼,而且代碼對于派生類來說都能正常地工作。或者換種說法,你向對象發送一條消息,讓對象自己做正確的事。 面向對象編程中的經典例子是形狀**Shape**。這個例子很直觀,但不幸的是,它可能讓初學者困惑,認為面向對象編程只適合圖形化程序設計,實際上不是這樣。 形狀的例子中,有一個基類稱為**Shape**,多個不同的派生類型分別是:**Circle**,**Square**,**Triangle**等等。這個例子之所以好用,是因為我們可以直接說“圓(Circle)是一種形狀(Shape)”,這很容易理解。繼承圖展示了它們之間的關系: ![形狀繼承圖](https://lingcoder.gitee.io/onjava8/images/1562204648023.png) 向上轉型就像下面這么簡單: ~~~ Shape s = new Circle(); ~~~ 這會創建一個**Circle**對象,引用被賦值給**Shape**類型的變量 s,這看似錯誤(將一種類型賦值給另一種類型),然而是沒問題的,因此從繼承上可認為圓(Circle)就是一個形狀(Shape)。因此編譯器認可了賦值語句,沒有報錯。 假設你調用了一個基類方法(在各個派生類中都被重寫): ~~~ s.draw() ~~~ 你可能再次認為**Shape**的`draw()`方法被調用,因為 s 是一個**Shape**引用——編譯器怎么可能知道要做其他的事呢?然而,由于后期綁定(多態)被調用的是**Circle**的`draw()`方法,這是正確的。 下面的例子稍微有些不同。首先讓我們創建一個可復用的**Shape**類庫,基類**Shape**為它的所有子類建立了公共接口——所有的形狀都可以被繪畫和擦除: ~~~ // polymorphism/shape/Shape.java package polymorphism.shape; public class Shape { public void draw() {} public void erase() {} } ~~~ 派生類通過重寫這些方法為每個具體的形狀提供獨一無二的方法行為: ~~~ // polymorphism/shape/Circle.java package polymorphism.shape; public class Circle extends Shape { @Override public void draw() { System.out.println("Circle.draw()"); } @Override public void erase() { System.out.println("Circle.erase()"); } } // polymorphism/shape/Square.java package polymorphism.shape; public class Square extends Shape { @Override public void draw() { System.out.println("Square.draw()"); } @Override public void erase() { System.out.println("Square.erase()"); } } // polymorphism/shape/Triangle.java package polymorphism.shape; public class Triangle extends Shape { @Override public void draw() { System.out.println("Triangle.draw()"); } @Override public void erase() { System.out.println("Triangle.erase()"); } } ~~~ **RandomShapes**是一種工廠,每當我們調用`get()`方法時,就會產生一個指向隨機創建的**Shape**對象的引用。注意,向上轉型發生在**return**語句中,每條**return**語句取得一個指向某個**Circle**,**Square**或**Triangle**的引用, 并將其以**Shape**類型從`get()`方法發送出去。因此無論何時調用`get()`方法,你都無法知道具體的類型是什么,因為你總是得到一個簡單的**Shape**引用: ~~~ // polymorphism/shape/RandomShapes.java // A "factory" that randomly creates shapes package polymorphism.shape; import java.util.*; public class RandomShapes { private Random rand = new Random(47); public Shape get() { switch(rand.nextInt(3)) { default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } public Shape[] array(int sz) { Shape[] shapes = new Shape[sz]; // Fill up the array with shapes: for (int i = 0; i < shapes.length; i++) { shapes[i] = get(); } return shapes; } } ~~~ `array()`方法分配并填充了**Shape**數組,這里使用了 for-in 表達式: ~~~ // polymorphism/Shapes.java // Polymorphism in Java import polymorphism.shape.*; public class Shapes { public static void main(String[] args) { RandomShapes gen = new RandomShapes(); // Make polymorphic method calls: for (Shape shape: gen.array(9)) { shape.draw(); } } } ~~~ 輸出: ~~~ Triangle.draw() Triangle.draw() Square.draw() Triangle.draw() Square.draw() Triangle.draw() Square.draw() Triangle.draw() Circle.draw() ~~~ `main()`方法中包含了一個**Shape**引用組成的數組,其中每個元素通過調用**RandomShapes**類的`get()`方法生成。現在你只知道擁有一些形狀,但除此之外一無所知(編譯器也是如此)。然而當遍歷這個數組為每個元素調用`draw()`方法時,從運行程序的結果中可以看到,與類型有關的特定行為奇跡般地發生了。 隨機生成形狀是為了讓大家理解:在編譯時,編譯器不需要知道任何具體信息以進行正確的調用。所有對方法`draw()`的調用都是通過動態綁定進行的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看