2010-01-20 52 views

回答

9

有時候你會對所有繼承類需要設置的實例變量進行一些常見的初始化。當你擴展它時,你會實例化一個抽象類,而具體類有一個構造函數,它將提供參數給抽象類的構造函數。

+2

一個例子是javax.swing.AbstractAction – 2010-01-20 23:25:43

5

它們仍然可以由繼承自其中的類的構造函數調用,從而使得代碼重構在抽象類中具有構造函數很有用。

3

如果您在抽象類中有未初始化的最終字段,則需要在構造函數中初始化它們。

E.g.

abstract class A { 
    final int x; 
} 

不會編譯而沒有分配給x構造。

3

如果你的類沒有聲明一個構造函數,那麼javac會爲你創建一個無參數,無所事事的構造函數。然後,當你的子類被初始化時,它會調用生成的無操作構造函數,並且生活很好。

但是,如果你的類聲明瞭任何構造函數,javac將不會爲你創建一個構造函數。在這種情況下,子類構造函數需要顯式調用父類的構造函數。否則,您將無法初始化父類的成員,如上面的答案所述。

2

抽象類的構造函數由子類使用(使用super(params)從子類構造函數中調用)。

您應該使這些構造函數protected清楚。

2

您不實例化抽象類,但構造函數在實例化子類時調用。

使用可能是初始化常見的屬性,即。

import java.util.List; 
import java.util.ArrayList; 
abstract class BaseClass { 
    protected List list; // visible from subclasses 

    public BaseClass() { 
     System.out.println("to abstract..."); 
     // common initialization to all subclasses 
     list = new ArrayList(); 
     list.add("a"); 
     list.add("a"); 
     list.add("a"); 
    } 
} 

class ConcreteClass extends BaseClass { 
    public ConcreteClass(){ 
     // The list is initialized already 
     System.out.println("now it is concrete and the list is: = "+ this.list); 


    } 
} 

class TestAbstractClass { 
    public static void main(String [] args) { 
     BaseClass instance = new ConcreteClass(); 
    } 

} 

輸出

$ java TestAbstractClass 
to abstract... 
now it is concrete and the list is: = [a, a, a] 
1

去重複常識/行爲。

E.g.一輛汽車:你所有的汽車將由一個車身和四個車輪和一個發動機構成。所以你通過調用Body(),Wheel(int x),Engine()等函數,在抽象Car類的構造函數中完成這部分構造。每個特定的汽車類都會有他們自己的Body(),Wheel()和Engine()的實現 - 但他們都會按照相同的步驟從它們中構建汽車,所以不需要在每個類中重複這些步驟類。在這種情況下,你可以在祖先中實現這個共同的行爲。

-1

我同意,構造函數是假設會有實例創建的。如果你有很多通用的代碼,你可以考慮創建一個構造函數,但是把它放在一個init()方法中會好很多。

+1

這是不好的建議,然後每個Inheirting類都需要記得調用super。init()並且它變得很亂,這是非標準的,非常糟糕的建議。 – 2010-01-21 18:15:55