Paolo's Lösung ist gut (+1), aber er hat die Fehlermeldung nicht erklärt, also lass mich das versuchen. Das Problem rührt von der Tatsache her, dass jede Methode einen Rückgabetyp benötigt. Ihre ursprüngliche Definition von apply
und dual
hat ein Objekt class A
zurückgegeben, daher war der implizite Rückgabetyp von beiden A
. Das bedeutet, dass A
für Clients sichtbar sein muss - wie sonst könnten sie die Funktion aufrufen oder auf die val
zugreifen? Da beide - und auch ihr Elternobjekt - öffentlich sind, sind sie global sichtbar. Sie haben jedoch A private
deklariert, was bedeutet, dass es außerhalb seines Pakets nicht sichtbar sein muss. Es gibt also einen Konflikt, der vom Compiler nicht gelöst werden kann.
Die allgemeine Regel ist, dass alle Parameter und der Rückgabetyp von Funktionen/Membern (mindestens) denselben Sichtbarkeitsbereich haben müssen wie das verweisende Member selbst *. Eine triviale Möglichkeit, dieses Problem zu lösen, wäre daher, die Sichtbarkeit von und dual
auf private
zu reduzieren. Das würde den Compiler zufrieden stellen, aber nicht Sie :-)
Ihre Lösung löst das Problem, indem Sie den statischen Rückgabetyp in eine public
-Eigenschaft ändern, die somit dieselbe Sichtbarkeit wie die darauf bezogenen Member hat. Der dynamische Typ des zurückgegebenen Objekts ist immer noch class A
, dies muss jedoch für Clients nicht sichtbar sein. Dies ist ein klassisches Beispiel für das Prinzip "program to interfaces, not implementations".
Beachten Sie, dass dieses Prinzip in vollem Umfang anzuwenden, könnte man class A
in eine private
innere Klasse von object A
drehen, damit es macht innaccessible auch für andere Klassen im gleichen Paket:
trait A {
//...
}
object A {
def apply: A = dual
lazy val dual: A = new AImpl
private class AImpl extends A {
//some irrelevant logic...
}
}
* zu pedantisch sein, das umgebende Klasse/Objekt kann die Sichtbarkeit ihrer Mitglieder reduzieren, wie hier:
private class Holder {
def member = new Hidden
}
private class Hidden
wo member
ist public
aber seine einschließende Klasse ist private
, effektiv versteckt seine Mitglieder aus der externen Welt. Der Compiler gibt also hier keine Beschwerden ab.
hehehe Zugang zu jedem anderen privaten –
@ AK4749 gut, schließlich ist es ihr Begleiter wir reden. Es ist nicht so, dass die Klasse es _anyone_ erlaubt, auf ihre Privatsphäre zuzugreifen ... Obwohl auf _reflection _... –