<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## [為什么需要 RTTI](https://lingcoder.gitee.io/onjava8/#/book/19-Type-Information?id=%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81-rtti) 下面看一下我們已經很熟悉的一個例子,它使用了多態的類層次結構。基類`Shape`是泛化的類型,從它派生出了三個具體類:`Circle`、`Square`和`Triangle`(見下圖所示)。 ![多態例子Shape的類層次結構圖](https://lingcoder.gitee.io/onjava8/images/image-20190409114913825-4781754.png) 這是一個典型的類層次結構圖,基類位于頂部,派生類向下擴展。面向對象編程的一個基本目的是:讓代碼只操縱對基類(這里即`Shape`)的引用。這樣,如果你想添加一個新類(比如從`Shape`派生出`Rhomboid`)來擴展程序,就不會影響原來的代碼。在這個例子中,`Shape`接口中動態綁定了`draw()`方法,這樣做的目的就是讓客戶端程序員可以使用泛化的`Shape`引用來調用`draw()`。`draw()`方法在所有派生類里都會被覆蓋,而且由于它是動態綁定的,所以即使通過`Shape`引用來調用它,也能產生恰當的行為,這就是多態。 因此,我們通常會創建一個具體的對象(`Circle`、`Square`或者`Triangle`),把它向上轉型成`Shape`(忽略對象的具體類型),并且在后面的程序中使用`Shape`引用來調用在具體對象中被重載的方法(如`draw()`)。 代碼如下: ~~~ // typeinfo/Shapes.java import java.util.stream.*; abstract class Shape { void draw() { System.out.println(this + ".draw()"); } @Override public abstract String toString(); } class Circle extends Shape { @Override public String toString() { return "Circle"; } } class Square extends Shape { @Override public String toString() { return "Square"; } } class Triangle extends Shape { @Override public String toString() { return "Triangle"; } } public class Shapes { public static void main(String[] args) { Stream.of( new Circle(), new Square(), new Triangle()) .forEach(Shape::draw); } } ~~~ 輸出結果: ~~~ Circle.draw() Square.draw() Triangle.draw() ~~~ 基類中包含`draw()`方法,它通過傳遞`this`參數傳遞給`System.out.println()`,間接地使用`toString()`打印類標識符(注意:這里將`toString()`聲明為`abstract`,以此強制繼承者覆蓋該方法,并防止對`Shape`的實例化)。如果某個對象出現在字符串表達式中(涉及"+"和字符串對象的表達式),`toString()`方法就會被自動調用,以生成表示該對象的`String`。每個派生類都要覆蓋(從`Object`繼承來的)`toString()`方法,這樣`draw()`在不同情況下就打印出不同的消息(多態)。 這個例子中,在把`Shape`對象放入`Stream<Shape>`中時就會進行向上轉型(隱式),但在向上轉型的時候也丟失了這些對象的具體類型。對`stream`而言,它們只是`Shape`對象。 嚴格來說,`Stream<Shape>`實際上是把放入其中的所有對象都當做`Object`對象來持有,只是取元素時會自動將其類型轉為`Shape`。這也是 RTTI 最基本的使用形式,因為在 Java 中,所有類型轉換的正確性檢查都是在運行時進行的。這也正是 RTTI 的含義所在:在運行時,識別一個對象的類型。 另外在這個例子中,類型轉換并不徹底:`Object`被轉型為`Shape`,而不是`Circle`、`Square`或者`Triangle`。這是因為目前我們只能確保這個`Stream<Shape>`保存的都是`Shape`: * 編譯期,`stream`和 Java 泛型系統確保放入`stream`的都是`Shape`對象(`Shape`子類的對象也可視為`Shape`的對象),否則編譯器會報錯; * 運行時,自動類型轉換確保了從`stream`中取出的對象都是`Shape`類型。 接下來就是多態機制的事了,`Shape`對象實際執行什么樣的代碼,是由引用所指向的具體對象(`Circle`、`Square`或者`Triangle`)決定的。這也符合我們編寫代碼的一般需求,通常,我們希望大部分代碼盡可能少了解對象的具體類型,而是只與對象家族中的一個通用表示打交道(本例中即為`Shape`)。這樣,代碼會更容易寫,更易讀和維護;設計也更容易實現,更易于理解和修改。所以多態是面向對象的基本目標。 但是,有時你會碰到一些編程問題,在這些問題中如果你能知道某個泛化引用的具體類型,就可以把問題輕松解決。例如,假設我們允許用戶將某些幾何形狀高亮顯示,現在希望找到屏幕上所有高亮顯示的三角形;或者,我們現在需要旋轉所有圖形,但是想跳過圓形(因為圓形旋轉沒有意義)。這時我們就希望知道`Stream<Shape>`里邊的形狀具體是什么類型,而 Java 實際上也滿足了我們的這種需求。使用 RTTI,我們可以查詢某個`Shape`引用所指向對象的確切類型,然后選擇或者剔除特例。
                  <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>

                              哎呀哎呀视频在线观看