2011-11-28 20 views
1

的亞型。雖然這種按預期工作:隱私內部類和可訪問性,從我在使用的內部類,方法和構造私人註釋困難外型

trait A { 
    protected def lala =() 
} 

trait B extends A { 
    lala 
} 

下列不:

trait A { 
    class Lala protected() 
} 

trait B extends A { 
    new Lala 
} 

無論是做這個的:

trait A { 
    class Lala private[A]() 
} 

trait B extends A { 
    new Lala 
} 

唯一的辦法解決是這樣的:

object Screwed { 
    trait A { 
    class Lala private[Screwed]() 
    } 

    trait B extends A { 
    new Lala 
    } 
} 

是否真的斯卡拉這裏失敗Ť o提供一個清晰的機制,還是我錯過了什麼?我的猜測應該是private[this.type],但scalac根本不想吞下去......

回答

6

好,

trait A { 
    class Lala protected() 
    new Lala 
} 

沒有任何編譯。該錯誤消息似乎很合理:

error: constructor Lala in class Lala cannot be accessed in trait A 
Access to protected constructor Lala not permitted because 
enclosing class trait A in object $iw is not a subclass of 
class Lala in trait A where target is defined 

保護訪問意味着你只能從類或子類訪問構造函數。你試圖從封閉的特質中調用它。你可以做的一件事是這樣的:

trait B extends A { 
    class Gaga extends Lala 
    new Gaga 
} 

我不希望你的第三個例子編譯,出於類似的原因。

還要注意一個受保護的構造和protected class之間的區別。因此,例如:

trait A { 
    protected class P 
    class U // unprotected 
} 

class B extends A { 
    new P // OK 
    new U // OK 
} 

val b = new B 
new b.P // error 
new b.U // OK 
+0

事實上'受保護的類'是適合我的解決方案 –

0

受保護的人應該肯定能工作,你會得到什麼錯誤?對於私人用戶來說,你定義的範圍控制着他們的可見性(所以在特質A中,如果你給出了A的可見性,它在B中顯然是不可見的)。在最後一個例子中,你已經將範圍賦予了Screwed,因此Screwed中的任何內容都能夠看到私有類。順便說一句,我喜歡寫訪問修飾符的第一件事就是在一個代碼行,以便方便閱讀

您使用的是什麼版本的斯卡拉和你所說的「不工作」是什麼意思?

HTH!

+0

'的錯誤:在類的構造函數啦啦啦啦不能特質B'訪問。作爲路易指出,'protected'指Lala'的'範圍,而不是'A',並且似乎沒有成爲在__A知名度或A__亞型的任何可能的範圍。我原本以爲我會從'private [A]'或至少''protected [A]''得到這個。 –

+0

@Sciss也許你需要一個'protected class'?我已經更新了我的答案。 –

+0

感謝Luigi,我認爲返回一個'protected'內部類的實例會產生'Lala''逃避'它的上下文的問題,但是你是對的,這是有效的! –

1

這也適用於所期望的可見性(Lala只能從AA亞型實例化)。

trait A { 
    class Lala private[A]() 
    protected def newLala = new Lala 
} 

trait B extends A { 
    newLala 
} 

我不知道什麼是像protected[A]目的,如果它不能在這種情況下工作。