簡體   English   中英

調用子類構造函數的超類對象? 這是如何運作的?

[英]Super class object invoking a subclass constructor? How does that work?

public class NewClass 
{ 
    public static class superclass 
    { 
        static void print() 
        { 
            System.out.println("print in superclass."); 
        } 
    } 
    public static class subclass extends superclass 
    { 
        static void print() 
        { 
            System.out.println("print in subclass."); 
        } 
    } 

    public static void main(String[] args) 
    { 
        superclass A = new superclass(); 
        superclass B = new subclass(); //This line?
        A.print(); 
        B.print(); 
    } 
} 

我在從 geeksforgeeks學習靜態綁定時遇到了這段代碼。 我無法理解這一行:

超類 B = 新的子類();

不確定這是如何工作的。 基本上,我們是在創建超類的對象並調用子類的構造函數嗎? 這對我來說沒有多大意義,因為我一直看到並習慣於: A obj = new obj(); 類型對象創建。

在准備我的答案時,我發現我不得不以兩種不同的含義使用超類和子類這兩個詞。 我將這些類重命名為ThingCar並使用“超類”和“子類”作為一般概念。

public class NewClass 
{ 
    public static class Thing
    { 
        static void print() 
        { 
            System.out.println("print in superclass."); 
        } 
    } 
    public static class Car extends Thing
    { 
        static void print() 
        { 
            System.out.println("print in subclass."); 
        } 
    } 

    public static void main(String[] args) 
    { 
        Thing A = new Thing(); 
        Thing B = new Car(); //This line?
        A.print(); 
        B.print(); 
    } 
}

表達式new Car()總是創建一個Car類型的實例。 總是。 結果是 [a reference to] Car的實例。

現在,您可以將 [a reference to] Car的實例存儲到允許Car實例的任何類型的變量中。 那就是:

  • 一個Car類型的變量,
  • Car任何超類聲明的變量(這與Thing B聲明匹配),
  • Car直接或間接實現的接口類型聲明的變量。

那么,這行代碼會發生什么

    Thing B = new Car(); //This line?

它創建了一個新的Car實例,因此當然會調用Car構造函數 (*1) (*2)。 然后它將對該實例的引用存儲在變量B ,這允許所有類型的Thing實例,只要它們從Thing繼承並因此支持Thing對象所期望的一切。

什么發生在

    B.print();

它調用B引用的實例的print()方法。 由於該實例是Car實例,您將獲得Car.print()結果,而不是Thing.print()

補充幾點:

如果Car有一些在Thing找不到的其他方法(例如drive()方法),編譯器將不允許您在B上調用它們,因為並非所有Thing對象都有它們,但只有一些專門的Thing版本(即Car那些)。

我建議習慣 Java 命名約定,例如類名總是以大寫字母開頭,變量以小寫字母開頭。 Java 人太習慣這些約定了,以至於我們發現閱讀不遵循這些規則的代碼真的很令人困惑。

(*1) 在您的情況下,構造函數沒有明確定義,而是由 Java 編譯器自動生成。

(*2) 子類構造函數總是調用其超類的構造函數,依此類推直到Object構造函數,以初始化子類從其超類繼承的實例的所有方面。

抱歉,我自己對 Java 還是很陌生。 您能否提供以下實例:

public static void main(String[] args) 
    { 
        Thing A = new Thing(); 
        Thing B = new Car(); //This line?
        A.print(); 
        B.print(); 
     }

將用於僅創建汽車對象? 如:

 public static void main(String[] args) 
     { 
         Thing A = new Thing(); 
         Car B = new Car(); //This line?
         A.print(); 
         B.print(); 
     } 

我猜想通過調用子類的構造函數來創建對象的實例是什么,但不支持所有方法。 我有點困惑這在實踐中如何有價值?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM