2012-09-23 86 views
0

我想知道是否有辦法在不破壞封裝的情況下做到這一點,我希望抽象類依賴實現子類中定義的參數。像這樣:抽象類從實現子類中獲取參數?

public abstract class Parent { 

    private int size; 
    private List<String> someList; 

    public Parent() { 
     size = getSize(); 
     someList = new ArrayList<String>(size); 
    } 

    public abstract int getSize(); 

} 

public class Child extends Parent { 

    @Override 
    public int getSize() { 
     return 5; 
    } 

} 

這難看嗎?有沒有更好的辦法?或許更重要的是,這是一個好主意嗎?

編輯:

類在一個框架的背景下創建的,所以默認參數的構造函數始終是一個叫(事實上,父類擴展了另一個類)。 size參數僅用於說明目的,我不打算將它用於List實現。

回答

4

不,不難看。這種模式被命名爲「模板方法」。但是,當方法不是一個簡單的getter,而是實現業務邏輯的東西時,它通常更有用。

在你的情況其他的解決辦法是在父類中定義受保護的構造和孩子相關的參數調用它:

public abstract class Parent { 

    private int size; 
    private List<String> someList; 

    protected Parent(int size) { 
     this.size = size; 
     someList = new ArrayList<String>(size); 
    } 

    public int getSize() { 
     return size; 
    } 

} 

public class Child extends Parent { 
    public Child() { 
     super(5); 
    } 
} 
+0

嗨AlexR,謝謝你的回答,但有一些這種方法的影響,我沒有提到足夠快,我已經編輯他們到我的問題。抱歉。 –

2

如果構造函數是您使用的唯一地方getSize(),只需要它作爲構造函數參數。

但更重要的是,爲什麼你在乎尺寸?除非你知道有一個問題,只要使用默認的大小和其他人一樣:

public abstract class Parent { 

    private List<String> someList = new ArrayList<String>(); 

    // use default constructor  
} 
+0

對不起,我應該澄清更多,類是在一個框架的上下文,所以默認的無參構造函數總是被調用的。大小參數僅用於說明目的,我不打算將它用於List實現。 –

1

的模式是不難看,除了當你嘗試在構造函數中使用它。它允許您以一種意想不到的方式修改Child。

public class Child extends Parent { 

    private int mySize = 5; 

    @Override 
    public int getSize() { 
     // The -1 is only to help clarify what happens 
     return mySize - 1; 
    } 

} 

如果你現在創建一個實例兒童它實際上拋出一個異常,因爲負的容量是不允許的。您應該認識到,類的屬性只在父構造函數完成後才初始化。 (如果使用Parent構造函數設置了一個屬性並且在Child中定義了一個默認值,它將會愉快地覆蓋剛纔在Parent()中設置的值)