Was sind die Vorteile von Scalas Begleitobjekten gegenüber statischen Methoden?

50

Scala hat kein statisches Schlüsselwort, sondern eine ähnliche Funktionalität durch Begleitobjekte. Hinter den Kulissen werden die Companion-Objekte zu Klassen kompiliert, die statische Methoden haben. Das alles ist syntaktischer Zucker. Was sind die Vorteile dieser Designauswahl? Nachteile? Haben andere Sprachen ähnliche Konstrukte?

Verhalten
quelle

Antworten:

49

Hier sind einige Gründe, die für Sie je nach Ihren Vorlieben mehr oder weniger überzeugend sein können:

  1. Diskontieren Sie es nicht einfach als "syntaktischen Zucker". Während Sie vielleicht sagen, dass etwas nur syntaktischer Zucker ist, ist es doch der Zucker, der Ihr Leben versüßt - als Programmierer genauso wie als Kaffee- oder Teetrinker.

  2. Singletons - Jede Scala objectist von Natur aus ein Singleton. In Anbetracht der Tatsache, dass in der Java-Welt Singletons auf unterschiedlichste Weise implementiert werden und häufig Fehler in ihrer Implementierung auftreten, können Sie einen Fehler in Scala nicht so einfach machen. Schreiben objectstatt classmacht es zu einem Singleton und Sie sind fertig.

  3. Zugriff auf statische Methoden: Auf die statischen Methoden in Java kann von Objekten aus zugegriffen werden. Angenommen, Sie haben eine Klasse Cmit einer statischen Methode fund einem Objekt cvom Typ C. Dann sollten Sie aufrufen C.f, aber Java erlaubt es Ihnen (wenn auch mit einer Warnung) zu verwenden c.f, was, wenn Sie aus dem Scala-Hintergrund kommen, eigentlich keinen Sinn ergibt, weil Objekte eigentlich keine Methode haben f.

  4. Klare Trennung: In Java können Sie statische und nicht statische Attribute und Methoden in einer Klasse mischen. Wenn Sie diszipliniert arbeiten, wird dies kein Problem. Wenn Sie (oder sonst jemand) dies nicht tun, verschachteln sich statische und nicht statische Teile, und es ist schwer, dies auf einen Blick zu erkennen Was ist statisch und was nicht. In Scala ist alles, was sich im Companion-Objekt befindet, eindeutig nicht Teil der Laufzeitobjekte der entsprechenden Klasse, sondern steht in einem statischen Kontext zur Verfügung. Wenn es umgekehrt in einer Klasse geschrieben ist, steht es Instanzen dieser Klasse zur Verfügung, jedoch nicht aus einem statischen Kontext. Dies ist in Java besonders lästig, wenn Sie Ihre Klasse mit statischen und nicht statischen Initialisierungsblöcken versehen. Dies kann in Bezug auf die dynamische Ausführungsreihenfolge sehr schwer nachvollziehbar sein.

  5. Weniger Code: Sie müssen nicht jedes Attribut oder jede Methode in einem statischen Wort hinzufügen object, um den Code übersichtlicher zu gestalten (in der Tat kein wesentlicher Vorteil).

Nachteile sind viel schwerer zu finden. Man könnte argumentieren, dass die statischen und nicht-statischen Teile zusammen gehören sollten, aber durch das Scala-Konzept der Begleitobjekte getrennt sind. Zum Beispiel mag es seltsam erscheinen, ein Klassendiagramm zu haben, aber am Ende müssen zwei Dinge im Code erstellt und herausgefunden werden, welches Attribut wohin führt.

Frank
quelle
1
Ich habe auch gelesen, dass Statik nicht in eine reine OOP-Software gehört. Wenn Sie statisches Verhalten benötigen, verwenden Sie eine eigene Klasse und erstellen Sie ein (Singleton-) Objekt davon, das das (potenzielle) statische Verhalten der Objekte einer anderen Klasse verwaltet.
K ..
1
"Das Schreiben eines Objekts anstelle einer Klasse macht es zu einem Singleton, und Sie sind fertig." Ich mag Singletons selbst nicht besonders, aber ich muss zugeben, dass die Direktheit dieses speziellen "syntaktischen Zuckers" einen gewissen Reiz hat.
Ed Hastings
3
Keiner der Punkte 1 bis 5 (und auch nicht alle zusammen) benötigt zur Laufzeit ein echtes Begleitobjekt, um implementiert zu werden. Alle von ihnen könnten leicht zu reinem syntaktischen Zucker gemacht werden, ohne Auswirkungen auf die Laufzeit. Der einzige wirkliche Grund, ein Laufzeit-Begleitobjekt zu haben, ist die Antwort von Alexey Romanov.
mas.morozov
"Nachteile sind viel schwerer zu finden." Performance? Der Zugriff auf eine Objektmethode generiert einen ifnonnullBytecode etc im Vergleich zu simply invokeStatic.
Eduardo Pareja Tobes
33

Ein weiterer Vorteil ist, dass objects im Gegensatz zu statischen Methoden Schnittstellen / Merkmale implementieren kann.

Alexey Romanov
quelle
8
Ich denke, das ist der Hauptunterschied zwischen einem Companion-Objekt und einer Klasse mit statischen Methoden. Ein Companion-Objekt ist polymorph und kann als Argument an Methoden übergeben werden, die eine Schnittstelle / ein Merkmal erwarten.
Dcastro
4

Companion-Objekte sind der erste Ort, an dem nach Implicits gesucht wird. Danach untersucht scala Predef und anschließend die expliziten "import" -Anweisungen in dieser bestimmten Quelldatei.

Ich bin kein Java-Entwickler genug, um zu wissen, ob die Java-Sprache oder die Java-Bibliotheken einen vergleichbaren Mechanismus bieten.

Gen T
quelle