簡體   English   中英

java中的方法重寫和繼承

[英]Method overriding and Inheritance in java

請考慮以下代碼段:

class A{ /* assume static and non static block are here */ }
class B extends A{ /* assume static and non static block are here */ }

在主要方法中,

 new B();

所以初始化的順序是:

  1. A類的靜態成員初始化
  2. B類的靜態成員初始化
  3. A類的非靜態成員初始化
  4. 然后在構造函數A中執行代碼
  5. B類的非靜態成員初始化
  6. 然后在構造函數B中執行代碼

現在來看看這段代碼,

class A{
    A(){
        this.m(); //line 1
    }

    void m(){
        System.out.println("A.m()");
    }
  }

  class B extends A{
     void m(){
        System.out.println("B.m()");
    }
  }

在主要方法中,

 new B();

當正在執行構造函數A的代​​碼時,它只能看到類A中的方法m,因為尚未為類B初始化非靜態成員(根據我提到的順序)。 但結果是“Bm()”。 (已經執行了子類的方法)考慮到我提到的順序,有人可以解釋這里發生的事情(方法覆蓋)嗎?

當正在執行構造函數A的代​​碼時,它只能看到類A中的方法m,因為尚未為類B初始化非靜態成員(根據我提到的順序)。

您假設方法是初始化的“非靜態成員”的一部分。 事實並非如此 - 當A構造函數完成時, B字段確實被初始化了。

只要在Java中創建對象,就會設置其類型並且永遠不會更改。 所有字段分配了足夠的空間 - 但這些字段實際上是從繼承層次結構的頂部向下初始化的。

所以,是的,如果你從構造函數調用一個重寫方法,它將在一個上下文中執行,其中一些它想要使用的字段沒有被初始化 - 所以你應該盡可能避免這樣做。

無論派生類是否已初始化,都會發生方法重寫。

這就是為什么你應該避免在初始化器中調用虛方法。

暫無
暫無

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

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