2015-02-23 65 views
2

我一個有一個特點:部隊繼承類來實現方法爲保護

trait A { 
    def some: Int 
} 

和對象在混合它:

object B extends A { 
    def some = 1 
} 

的問題是,有沒有申報方式someA中,所有繼承對象都必須將some方法聲明爲protected,例如?有什麼東西會讓編譯器在Bsome的上述實現中大吼一聲?

更新: 只是澄清我的問題的目的:在一個組織內部,有一些軟件開發標準已經達成共識。這些標準,例如'some方法在從trait A繼承時總是被聲明爲private',通常通過列出所有標準或通過諸如詹金斯等工具的規格或文檔進行通信......我想知道如果我們可以更進一步,並在代碼中擁有這些標準,這將爲糾正Jenkins引發的問題節省大量時間。

更新2: 我能想到的解決方案如下:

abstract class A(
    protected val some: Int 
){ 
    protected def none: String 
} 

使用abstract class,而不是trait,並有我需要在默認情況下被傳爲protected的功能或值構造函數:

object B extends A(some = 1) { 
    def none: String = "none" 
} 

注意,在這種情況下,some默認情況下protected除非開發板的每個決定通過另一種方法公開它。但是,不能保證,默認情況下,none也將是protected

這適用於我上面描述的用例。這個實現的問題是,如果我們有一個層次結構abstract class es,我們必須將父級的所有構造函數參數添加到層次結構中的每個繼承子級。例如:

abstract class A(
    protected val some: Int 
) 

abstract class B(
    someImp: Int, 
    protected val none: String  
) extends A(some = someImp) 

object C extends B(
    someImp = 1, 
    none = "none"  
) 

相比之下,使用trait S,我們本來可以簡單地寫:

trait A{ 
    protected val some: Int 
} 

trait B extends A{ 
    protected val none: String  
} 

object C extends B{ 
    val some = 1 
    val none = "none" 
} 

回答

1

我看不出有任何直接的方式從選擇一個更寬闊的視野限制小類繼承成員。

這取決於你爲什麼要隱藏領域的一些,但如果目的只是爲了訪問現場禁止最終用戶,您可以使用餅圖案略加修改的形式:

trait A { 
    trait A0 { 
     protected def some: Int 
    } 
    def instance: A0 
} 

object B extends A { 
    def instance = new A0 { 
    def some = 5 
    } 
} 

是啊,它看起來討厭,但是編譯器會嚷嚷當有人試圖做的事:

B.instance.some 

這個解決方案的另一個版本是剛做這樣的事情在你的榜樣(加保護的成員「一些」,在A) ,但不要直接公開類型B的引用(總是返回引用的A型代替)

+0

這將解決部分問題,最終用戶將無法使用某種方法。但我真正想要的是,從我的特質繼承的開發人員將被迫將其聲明爲私有或受保護。因爲這不會阻止未來的開發者以一種暴露它的方式聲明'some'方法。 – Peter 2015-02-24 13:21:59