2012-05-14 80 views
0

我得到了一個基類型和一些派生類型。每個派生類型都有一個將由util類中的靜態final字段初始化的字段,並且基類型將使用該字段。 e.g如何在繼承層次結構中設計字段?

public BaseClass{ 
    protected String FLAG = ""; 

    public void someMethod(){ 
     // codes using FLAG 
    } 
} 

public DerivedClass1 implements BaseClass{ 
    protected String FLAG = Util.FLAG1; 
} 

public DerivedClass2 implements BaseClass{ 
    protected String FLAG = Util.FLAG2; 
} 

我的問題是

  1. 是設計好的?
  2. 我應該爲FLAG製作受保護的getter/setter,並在派生類中使用setter來初始化它嗎?
  3. 如果其他類別調用FLAG,例如if (baseClass.FLAG.equals(...)),我應該爲它公開getter/setter嗎?我不這麼認爲,因爲FLAG只是一個標誌,它有點像靜態字段。
+0

你試過了嗎? (沒關係 - 由於你的命名,它認爲這是一個靜態的領域。我希望你可以從移動安卓網站刪除評論。) –

回答

0

1-不,設計不好。你不應該重新定義標誌在子類中,但只有在超值賦給國旗:

public DerivedClass1 implements BaseClass{ 
    public DerivedClass1() { 
     this.flag = Util.FLAG1; 
    } 
} 

領域不應該被命名爲喜歡的一個常數,因爲它不是一個。 flag而不是FLAG

2-不一定。但是,您可以將其作爲基類構造函數的參數,以強制每個子類在構造時提供值。

3-從不直接訪問其他類的字段。絕對使用吸氣劑從外面訪問它。不,標誌不是靜態字段,因爲每個實例都有它自己的值。

+0

謝謝。但是第三個問題,實際上DerivedClass1的每個實例都有一些標誌(它們的值是相等的)。 –

+1

它們的值是相等的,但這不會使該字段保持靜態。您仍然需要一個DerivedClass1實例來訪問標誌值。 –

1

您的設計不正常,因爲子類字段隱藏了基類字段。如果你只是想以不同的方式分配在每個子類,基類的領域,這樣做在各自的構造 - 或者更好,委託給基類構造函數:

public BaseClass { 
    protected final String FLAG; 
    protected BaseClass(String flag) { this.FLAG = flag; } 
    ... 
} 

public DerivedClass1 extends BaseClass { 
    public DerivedClass1() { super(Util.FLAG1); } 
    ... 
} 

public DerivedClass2 extends BaseClass { 
    public DerivedClass2() { super(Util.FLAG2); } 
    ... 
} 

還注意到,這是對強大的Java約定來命名UPPER_CASE中的實例字段。所以你應該有一個protected String flag

至於另外兩個問題 - 如果您將設計更改爲上述內容,那麼flag字段爲final,您可以將其設置爲public,並讓其他人直接訪問它。這將是合法的設計,據我所知,但你可能會從其他許多Java開發人員這樣做皺眉:)

你提到添加一個設置器標誌,但我懷疑這會使任何意義(只是猜測,你可能真的想稍後改變那個標誌)。

+0

+1我同意,很好的答案。這裏的要點是你可以覆蓋方法(稱爲多態),但不能使用屬性。 – Brady

+0

謝謝。那麼如果其他類調用它,我必須使用'baseClass.getFlag()',對吧?順便說一句,我知道關於命名約定的東西,但我只是認爲標誌有點像語義學的靜態字段。 –

+0

這是一種錯誤的語義引導你的想法 - 當Java開發者看到一個「FLAG」時,他直觀地認爲它是一個「靜態最終」字段 - 在你的情況下,這將是錯誤的。更高級的業務語義並不是推動var命名的原因。 –

0

我不喜歡這種設計,因爲你有一個只有數據不同的類,但是至少在行爲上不是這樣。

從只提供靜態工廠方法來創建實例創建壞 MyClass實例
public MyClass { 
    protected final String FLAG; 

    public static MyClass CreateClass1() { return new MyClass(Util.FLAG1); } 

    public static MyClass CreateClass2() { return new MyClass(Util.FLAG1); } 

    protected MyClass(String flag) { this.FLAG = flag; } 
} 

在這種情況下,你保護的用戶:我想如下構建它。你也避免了創建一個到目前爲止似乎不需要的類層次結構。