2011-02-24 95 views
24

我知道的是,編譯器在字節碼中寫入一個默認的無參數構造函數。但是如果我們自己編寫它,那個構造函數會自動調用。這種現象是構造函數重寫的嗎?構造函數覆蓋可能嗎?

回答

17

你所描述的並不是壓倒一切。如果您不指定默認構造函數,則 編譯器將創建一個默認構造函數。如果它是一個子類,它會調用 默認的父類的構造(super()),它也將初始化所有實例變量 由類型的默認值(0的數字類型確定的默認值,假的布爾值,或目標的零 )。

當子類具有相同的名稱,參數的數量/類型,以及與超類的實例方法相同的返回類型時,覆蓋會發生。在這種情況下,子類 將覆蓋超類的方法。 Information on overriding here

3

只要它們採用不同的參數,就可以有許多構造函數。但是編譯器放入一個默認的構造函數不會被稱爲「構造函數重載」。

+0

我不能否認你的答案,但OOP的基本規則,一般每個方法都必須重寫,提供了其不被聲明爲final。 – Gopal 2011-02-24 03:27:45

0

你的例子不是一個覆蓋。覆蓋技術上發生在一個子類中,但在本例中,構造函數方法在原始類中被替換。

+0

但是,正如您可以觀察到的那樣,重寫適用於具有相同數字簽名但定義不同的方法。所以我們真的重寫構造函數? – Gopal 2011-02-24 03:33:14

+2

不可以。最重要的概念只適用於繼承。你是否在找人告訴你,你的'教師'是錯的? – Corey 2011-02-24 04:35:27

3

無法重寫構造函數。構造函數可以視爲靜態的,子類不能重寫它的超級構造函數。

當然,您可以在超類構造函數中調用protected-method,然後在子類中覆蓋它以更改超類構造函數。但是,許多人建議不要使用這個技巧,以保護超類構造函數的行爲。例如,FindBugs會警告你一個構造函數調用非final方法。

21

構造函數不是正常的方法,它們不能被「覆蓋」。說一個構造函數可以被重載會意味着一個超類的構造函數將是可見的,並且可以被調用來創建一個子類的實例。這不是真的......一個子類默認沒有任何構造函數(除非無參數構造函數如果它擴展的類有一個)。它必須顯式聲明任何其他構造函數,並且這些構造函數屬於它,而不屬於它的超類,即使它們採用與超類構造函數相同的參數。

你提到的有關默認沒有參數構造函數的東西只是構造函數如何工作的一個方面,與重寫無關。

1

但是,如果我們自己編寫它,那麼 構造函數會自動調用。

這是不正確的。如果你稱之爲無參構造函數,那麼無論你是否自己編寫它,。如果您不在派生類中編寫顯式超級(...)調用,它也會自動調用。

這些都不構成構造函數重寫。 Java中沒有這樣的東西。 There is constructor overloading,即提供不同的參數集。

11

這是永遠不可能的。構造器重寫在Java中是不可能的。

這是因爲,

構造看起來像一個方法,但 名字應該是作爲類名,並沒有 返回值。

重寫意味着我們已經宣佈在超級類 ,恰好我們有 在子類中聲明它被稱爲 重寫。超類名與Sub 類名不同。

如果你想寫超級類 構造函數,子類,則子 類將可以把它看成不 構造,因爲名字應該 不匹配子類名稱的方法。 會給出編譯錯誤, 方法沒有返回值。所以 我們應該聲明爲void,那麼只有 它會編譯。


看一看下面的代碼:

Class One 
     { 
     .... 
     One() { // Super Class constructor 
      .... 
     } 

     One(int a) { // Super Class Constructor Overloading 
      .... 
     } 
} 

Class Two extends One 
        { 
        One() { // this is a method not constructor 
        .....  // because name should not match with Class name 
        } 

        Two() { // sub class constructor 
        .... 
        } 

        Two(int b) { // sub class constructor overloading 
        .... 
        } 
} 
0

還應當指出的是,你不能覆蓋的構造與超類的名字的構造函數的子類。 OOPS的規則告訴構造函數應該有名字作爲它的類名。如果我們試圖重載超類的構造函數,它將被視爲一個沒有返回類型的未知方法。

0

構造函數看起來像一個方法,但名稱應該是類名稱並且沒有返回值。

覆蓋意味着我們已經在超類中聲明瞭什麼,我們不得不在Sub類中聲明它被稱爲覆蓋。超類名和子類名是不同的。

如果您嘗試在Sub類中編寫超級類構造函數,那麼Sub類會將其視爲不構造函數的方法,因爲名稱不應與Sub類名稱匹配。它會給出一個編譯錯誤,方法沒有返回值。所以我們應該聲明爲無效,那麼只有它纔會被編譯。

0

在java中重寫的方法用於改進以前編寫的最新代碼性能。

一些類似的代碼顯示,我們在這裏創建基類的引用並創建派生類的phyisical實例。 在構造函數中重載是可能的。

InputStream fis=new FileInputStream("a.txt"); 
int size=fis.available(); 

大小將返回可能的字節總數A.TXT 所以

1

因爲構造函數不能在Java中被繼承和方法覆蓋要求繼承。因此,它不適用。

0

由於以下原因,構造函數重寫是不可能的。

構造函數名稱必須與類名稱相同。在繼承實踐中,您需要創建兩個具有不同名稱的類,因此兩個構造函數必須具有不同的名稱。所以構造函數重寫是不可能的,這個想法甚至沒有意義。

2

不,它不可能重寫構造函數。如果我們試圖做到這一點,那麼編譯器會出錯。在Java中這是不可能的。讓我們看看這個例子。它會問請寫一個返回類型的方法。意味着它會將該重寫的構造函數視爲一種方法而不是構造函數。

package com.sample.test; 

class Animal{ 

    public static void showMessage() 
    { 
     System.out.println("we are in Animal class"); 
    } 
} 

class Dog extends Animal{ 

    public void DogShow() 
    { 
     System.out.println("we are in Dog show class"); 
    } 

    public static void showMessage() 
    { 
     System.out.println("we are in overriddn method of dog class"); 
    } 
} 

public class AnimalTest { 

    public static void main(String [] args) 
    { 
     Animal animal = new Animal(); 
     animal.showMessage(); 

     Dog dog = new Dog(); 
     dog.DogShow(); 

     Animal animal2 = new Dog(); 
     animal2.showMessage(); 
    } 

} 
+0

結果:我們在動物類 我們在狗展示類 我們在動物類 – hitesh141 2015-04-30 13:05:35