2017-09-12 74 views
0

我有類似下面,我想編譯如何調用受限訪問的子類構造函數?

trait T{ 
    def a: Int 
} 

class A private(val a: Int, a2: Int) extends T{ 
    def add(b: Int): A = new A(a + b, a2 + 2*b) 
} 

object T{ 
    def make(a: Int): A = { 
    new A(a, 2*a) // doesn't compile 
} 

這裏類A有一個私有構造函數,因爲我想構建一個一個的唯一方法是通過構造T.make或用更新的方法A.add(在這個例子中,它們都是a 2 = 2 * a)。

但是因爲構造函數是私有的,所以它不能被父特徵T訪問。同樣也適用於受保護的。基本上,我需要一個反向保護?

注意:不令人滿意的解決方案是降低(太多)對構造函數的限制,可能是封裝私有。但我不希望任何其他的工程可能,但那些計劃中的工程。我可以降低當前文件中所有代碼的約束,但是我不知道該怎麼做。

+0

它應該工作。見[這裏](https://stackoverflow.com/questions/6919965/companion-object-cannot-access-private-variable-on-the-class)。此外,對於最佳做法,請參閱[此處](https://stackoverflow.com/a/30836828/5599298) – slouc

+0

@slouc您的第一個鏈接與REPL中的行爲相關(第二個鏈接是正常的)。 –

+2

關於最佳做法,這只是個人喜好,爲建造者功能(make,build,...)提供明確的名稱。我用備用構造函數繼續應用()大小寫類/純定義類。這裏不是我的情況,但我可以在示例 –

回答

3

有幾個選項。

  • 您可以重命名object Tobject A - 那麼它將有機會獲得A的私有成員

  • 您可以class A內到object T - 那麼你可以讓構造private[T],並T將有機會獲得到它。

  • 你也可以使它成爲私有包。當你說它會「降低限制太多」時,你是錯誤的。 scala中的包不一定是整個目錄。它甚至不需要是整個文件。您可以完全控制其內容,其目的是能夠完成您在此嘗試完成的任務。

+0

我不知道'私人[T]範圍 –

3

也許你應該把make(..)放入類A的伴侶對象,而不是特質T的伴侶對象。

object A { 
    def make(a: Int): A = { 
     new A(a, 2 * a) 
    } 
    } 
+1

中使用它確實有效。我(顯然)有一個更復雜的情況下,這不是很實際(例如:我有另一個T子類和公共構造函數與A構造函數共享功能)。但我可以找到我的出路 –

相關問題