Gibt es einen Fall, in dem ein Begleitobjekt (Singleton) für eine Klasse benötigt wird? Warum sollte ich eine Klasse Foo
erstellen, beispielsweise ein Begleitobjekt dafür erstellen?
Gibt es einen Fall, in dem ein Begleitobjekt (Singleton) für eine Klasse benötigt wird? Warum sollte ich eine Klasse Foo
erstellen, beispielsweise ein Begleitobjekt dafür erstellen?
Antworten:
Das Begleitobjekt bietet im Grunde einen Ort, an dem man "statische" Methoden einsetzen kann. Darüber hinaus hat ein Begleitobjekt oder Begleitmodul vollen Zugriff auf die Klassenmitglieder, einschließlich privater.
Begleitobjekte eignen sich hervorragend zum Einkapseln von Dingen wie Factory-Methoden. Anstatt zum Beispiel Foo
und FooFactory
überall zu haben, können Sie eine Klasse mit einem Begleitobjekt die Fabrikverantwortung übernehmen lassen.
Companion-Objekte sind nützlich zum Speichern von Status und Methoden, die allen Instanzen einer Klasse gemeinsam sind , jedoch keine statischen Methoden oder Felder verwenden. Sie verwenden reguläre virtuelle Methoden, die durch Vererbung überschrieben werden können. Scala hat wirklich nichts Statisches. Es gibt viele Möglichkeiten, wie Sie dies verwenden können, aber hier ist ein einfaches Beispiel.
abstract class AnimalCounter
{
var animals = 0
def name: String
def count()
{
animals += 1
println("%d %ss created so far".format(animals, name))
}
}
abstract class Animal
{
def companion: AnimalCounter
companion.count()
}
object Dog extends AnimalCounter
{
val name = "dog"
}
class Dog extends Animal
{
def companion = Dog
}
object Cat extends AnimalCounter
{
val name = "cat"
}
class Cat extends Animal
{
def companion = Cat
}
Welches erzeugt diese Ausgabe:
scala> new Dog
1 dogs created so far
scala> new Cat
1 cats created so far
scala> new Dog
2 dogs created so far
scala> new Cat
2 cats created so far
... und es ist ein guter Ort, um statische Factory-Methoden (nicht diesen DP) für begleitete Klassen zu speichern. Wenn Sie diese überladenen Factory-Methoden angeben (/ ... /), können Sie Ihre Klasse erstellen / initialisieren
ohne 'neu' (nicht wirklich so wichtig)
mit verschiedenen möglichen Parametersätzen (vergleiche mit dem, was Bloch in Effective Java über den Teleskopkonstruktor schreibt)
mit der Möglichkeit zu entscheiden, welche abgeleitete Klasse Sie anstelle der abstrakten (begleiteten) Klasse erstellen möchten
Beispielcode:
abstract class AbstractClass;
class RealThing(s: String) extends AbstractClass;
class AlternativeThing(i: Int) extends AbstractClass;
object AbstractClass {
def apply(s: String) = {
new RealThing(s)
}
def apply(i: Int) = {
new AlternativeThing(i)
}
}
// somewhere else you can
val vs = AbstractClass("asdf") // gives you the RealThing wrapped over string
val vi = AbstractClass(123) // gives you AlternativeThing wrapped over int
Ich würde die Objekt- / Basisklasse AbstractXxxxx nicht nennen, weil sie nicht schlecht aussieht: als würde man etwas Abstraktes erstellen. Geben Sie diesen Namen eine echte Bedeutung. Erwägen Sie die Verwendung unveränderlicher Fallmethoden ohne Methode und versiegeln Sie die abstrakte Basisklasse.
RealThing
und AlternativeThing
class sollte einen private
Konstruktor haben, der den Benutzer zwingt, die AbstractClass
has-Factory zu verwenden. class AlternativeThing private(i: Int) extends AbstractClass
Zusätzlich zu den Dingen Saem sagte in seiner Antwort sucht der Scala - Compiler auch für implizite Konvertierungen von Typen in den entsprechenden Begleiter Objekte (von der Quelle oder Ziel), so dass die Umwandlungen nicht importiert werden müssen.
Über den Grund für Singleton-Objekte in der allgemeinen Programmierung in Scala heißt es:
Wie in Kapitel 1 erwähnt, besteht eine Möglichkeit, in der Scala objektorientierter als Java ist, darin, dass Klassen in Scala keine statischen Elemente haben können. Stattdessen verfügt Scala über Singleton-Objekte (S. 65).
Ich sehe Begleitobjekte immer als Brücke , um sowohl funktionalen als auch objektorientierten Code in Scala zu schreiben. Oft brauchen wir nur reine Funktionen, die Eingaben benötigen und ein Verarbeitungsergebnis liefern. Das Einfügen dieser relevanten Funktionen in das Begleitobjekt erleichtert das Nachschlagen und Verwenden sowohl für mich selbst als auch für jemanden, der auf meinem Code aufbaut.
Darüber hinaus ist es eine sprachlich bereitgestellte Funktion, um das Singleton-Muster zu schreiben, ohne etwas zu tun. Dies ist besonders nützlich, wenn Sie einen Singleton benötigen, um einen Delegator für die Lebensdauer von JVM zu kapseln. Schreiben Sie beispielsweise eine einfache HTTP-Clientbibliothek in Scala, in der Sie einen zugrunde liegenden Java-Implementierungsdelegator kapseln und die Benutzer Ihrer API in einer reinen Welt leben lassen können.
Wenn Sie Klasse und Objekt in derselben Datei mit demselben Namen definieren, werden sie als Begleitklasse und Objekt bezeichnet. Scala hat kein statisches JAVA-Schlüsselwort. Sie können statisches als Begleitklasse und Objekt in Scala ersetzen.
Weitere Informationen finden Sie in der Scala-Programmierung unter Artikelklasse und Objektschlüsselwort
Zunächst bietet es eine klare Trennung zwischen statischen und nicht statischen Methoden. Außerdem bietet es eine einfache Möglichkeit, eine Singleton-Klasse zu erstellen.
Es kann auch Methoden von anderen Klassen und / oder Merkmalen erben, was mit statischen Java-Methoden nicht möglich ist. Und kann als Parameter übergeben werden.