2016-09-26 127 views
4

我剛剛開始講述Java的故事,但是我對Python有一些OOP體驗。我有以下的類層次結構:覆蓋java中的子類中的參數化構造函數

class A { 
    public A() {}; 
    public A(final java.util.Map dict) {}; 
} 

class B extends A { 
} 

public class Main { 
    public static void main() { 
    java.util.Map d = new java.util.HashMap(); 
    B b = new B(d); 
    } 
} 

附帶的代碼導致以下錯誤:

Main.java:16: error: constructor B in class B cannot be applied to given types; 
    B b = new B(d); 
     ^
    required: no arguments 
    found: Map 
    reason: actual and formal argument lists differ in length 
1 error 

我的期望是什麼,因爲所需的構造函數在基類中已經定義,是沒有必要定義另一個構造函數。爲什麼我需要爲子類定義一個子類,因爲除了調用super()之外,他們沒有做任何特殊的事情?有什麼特別的理由,爲什麼java編譯器要我在子類中定義構造函數?

+0

的問題,如「爲什麼語言這種方式工作」只能由回答語言的設計師,而不是這個社區。在Java中,構造函數不會被繼承。這是事實。除此之外的任何事情都是猜測。 – RealSkeptic

+1

[Java Constructor Inheritance](http://stackoverflow.com/questions/1644317/java-constructor-inheritance) – shmosel

+0

「是否有任何特殊原因,爲什麼java編譯器要我在子類中定義構造函數?」你的意思是除了James Gosling和Java標準委員會之外的其他任何理由認爲這種方式更好?不,沒有一個。 –

回答

4

當您實例化一個類時,必須調用該類的構造函數。

當Java類沒有構造函數時,編譯器會自動生成一個無參數構造函數,它允許您實例化不帶參數的類(在您的示例中,它允許new B())。

既然你嘗試用一個參數來實例B級,您必須聲明適當的構造函數調用您所選擇的父類的構造函數:

public B(Map dict) { 
    super(dict); 
} 
1

您需要聲明Parametrised構造在B類並呼籲從中超級如果你不想初始化任何東西在你的類B.

喜歡的東西:

import java.util.*; 

class B extends A 
{ 
    B(Map dict) { 
     super(dict); 
    } 
} 
0

爲什麼CON結構沒有繼承?構造函數用於初始化對象,通常當從一個類繼承你傾向於使用的通用功能,但創建可能會有所不同,那麼擴展構造函數的用法是什麼,你將只是有一個超級類,在這種情況下,在一個類中具有所有常用功能並且具有包含不同功能的Utility類將是更好的做法。

1

在Java中 - 當您用構造函數擴展某個A類時,B子類的構造函數總是必須調用它。如果A得到0個參數 - 你不必寫任何東西 - compiller會自動調用它。如果有更多的參數,你必須將它們傳遞給基礎構造函數super()。以下是一些示例:

public class A { 
    public A(int something) { 

    } 
} 

public class B extends A { 
    public B(int something) { 
     super(something); 
    } 
} 

public class C extends A { 
    public C() { 
     super(999); 
    } 
} 

//--------------------------------------------// 

public class A { 
    public A() { 

    } 
} 

public class B extends A { 
    public B(int something) { 
     super(); 
    } 
} 

public class C extends A { 
    public C(int something) { 
    } 
} 

public class D extends A { 
    public D() { 
     super(); 
    } 
} 

public class E extends A { 
    public E() { 

    } 
} 
1

默認構造函數是在沒有定義構造函數時自動創建的。你必須在B中添加默認構造函數來調用A的默認構造函數。

所以你的代碼需要以下

class B extends A 
{ 
    B(){ 
     super(); // calling super class default constructor 
    } 
    B(Map dict) { 
     super(dict); // calling super class single parameter(map) constructor 
    } 
} 

這樣

B b = new B(); //invokes A's Default Constructor 
B b = new B(d); //invokes A's Parameter Consturctor 

希望這是明確的