Paolo的解決方案很好(+1),但他沒有解釋錯誤信息,所以讓我試試看。問題源於每個方法都需要返回類型的事實。您的原始定義apply
和dual
返回了class A
的對象,因此兩者的隱式返回類型爲A
。這意味着A
必須對客戶可見 - 他們還能如何調用該功能或訪問val
?而且,因爲兩者都是公開的,所以它們是全球可見的。但是,您聲明A private
這意味着它不能在其包裝外部可見。所以有一個編譯器無法解決的衝突。
一般規則是,函數/成員的所有參數和返回類型必須具有(至少)與引用成員本身*相同的可見性範圍。因此解決這個問題的一個微不足道的方法是將apply
和dual
的可視性降低到private
。這將滿足編譯器,但不是你:-)
您的解決方案通過將靜態返回類型更改爲public
特徵,從而具有與引用它的成員相同的可見性來解決此問題。返回對象的動態類型仍然是class A
,但是,客戶端無需看到它。這是原理"program to interfaces, not implementations"的典型示例。
注意,這個原則適用於充分的程度,一個可以把class A
成private
內部類的object A
,從而使其innaccessible即使是同一個包中的其它類:
trait A {
//...
}
object A {
def apply: A = dual
lazy val dual: A = new AImpl
private class AImpl extends A {
//some irrelevant logic...
}
}
* 要按照規範,封閉類/對象可以減少其部件的可見性,如這裏:
private class Holder {
def member = new Hidden
}
private class Hidden
其中member
是public
,但其封閉類是private
,有效地將其成員從外部世界隱藏起來。所以編譯器在這裏沒有投訴。
到每個人士兵 –
呵呵呵訪問@ AK4749很好,畢竟這是她的同伴,我們正在談論。這不是像班級只允許_anyone_訪問她的私人...雖然_reflection _... –