2013-05-15 48 views
0

雖然編碼的,我遇到以下情況:計算類成員

我有一個類,姑且稱之爲C。現在

public class C { 
    private int A; 

    public C(...) { 
     ... 
    } 

    public void calculateA() { 
     A = 42; 
    } 

    public int getA() { 
    } 
} 

我的問題是,如何實現吸氣getA正確:它必須先計算任意類型的屬性A。我應該檢查A是否被定義,否則拋出異常?

或者我應該在getA中撥打calculateA如果沒有設置?

這種問題的最佳選擇是什麼?


編輯: OK,我給了一個壞榜樣。 A不能在構造函數中計算,因爲計算方法將返回同一類的新實例,這將導致無限遞歸。

+3

爲什麼不是一個在構造函數設置的默認值? – Shaded

+0

取決於。但如果它是一個整數,你將如何區分它與未設置的值? '0'是一個無效值嗎?這是一個長期運行的計算(例如,它真的很重要)嗎? –

+0

這對這個例子有意義。但就我而言,沒有任何默認值是合理的。 – George

回答

1

這是一個設計問題,有點不適合這個論壇。

如果客戶有責任在getA()之前致電calculateA(),那麼getA()如果尚未計算,可以拋出異常。 a是原始的事實是無關緊要的,您可以初始化爲無效值 - 例如如果它是長度類型的實體,則將其初始化爲-1 - 或使用另一個boolean變量或使用Integer,該值將爲空,無論如何。

瞭解這會創建一個時間依賴關係 - 客戶端需要以固定順序調用方法。這通常是令人難以接受的,但可能有情況來證明它,你必須調用Car.stop()之前調用Car.start()

另一方面,如果C「擁有」A那麼它有責任計算它。它可以通過幾種方式做到這一點:

  • 急切地在其<init>,如果所有必要的信息是avaialable
  • 懶洋洋/點播但緩存,調用需要calculateA()第一次A。每次
  • 計算的叫法,但getA()可能在這種情況下,誤導性名稱。
0

這取決於。如果計算是靜態的,你也可以從構造函數中調用calculateA()函數。

public C(...) { 
     ... 
     calculateA() 
    } 

public void calculateA() { 
    A = 42; 
} 

如果獲取()的合同規定,只有A有效和計算值將返回,返回之前計算A

如果A由於某種原因無法計算,並且如果在計算任何進一步無效的A之前在程序中停止執行有意義,請拋出異常。

2

我認爲 -

public class C { 
    private int A = Integer.MIN_VALUE; 
    ... 
    public int getA() { 
     if(A==Integer.MIN_VALUE)// Assume Integer.MIN_VALUE when it is not calculated 
      throw new RuntimeException(); 
     return A; 
    } 
} 

它不可能是100%的證據,因爲它假定Integer.MIN_VALUE無法計算值。

使實例變量A成爲Integer Object而不是原始的int,因此您可以將其設置爲null,以便更容易地確定狀態。

+1

排除了零爲「A」的有效值的可能性。 – Zutty

+0

呃...但它會是0,除非明確地設置爲別的東西(並假定0不是一個合理的值,這是沒有說明)。 –

+0

邑它真的是一個假設,0或MIN_VALUE或MAX_VALUE –

1

這是一個不好的例子,因爲int是一個原始類型。它從不爲空。它已初始化爲零。

但您的觀點對於參考類型有效。

我會認爲這是一個糟糕的設計,允許對私有成員進行空引用。構造函數應該初始化該對象以準備好100%。

+2

我不完全同意這一點。該對象必須在構造函數的末尾保持一致。在一些使用情況下,空指針可能是一致的,例如,表示節點的對象可以具有可能爲空的父節點(根節點的情況)。 –

+0

同意。我正在考慮像List孩子這樣的病例。將它初始化爲指向一個空的List實現是完全合理的。每次嘗試訪問它時,我都不必付出檢查的代價來查看它是否爲空。 – duffymo

+0

你的具體情況,知道空節點模塊根源在於,是適當回傳給用戶信息。或者我可能有一個特殊的Node實例,以及一個返回布爾值的方法isRoot()。 – duffymo