Was ist der Unterschied zwischen einem Objekt und einem Begleitobjekt in einer Klasse in Kotlin?
Beispiel:
class MyClass {
object Holder {
//something
}
companion object {
//something
}
}
Ich habe bereits gelesen, dass ein Begleitobjekt verwendet werden soll, wenn die enthaltenen Parameter / Methoden eng mit seiner Klasse zusammenhängen.
Aber warum gibt es auch die Möglichkeit, ein normales Objekt in der Klasse zu deklarieren? Weil es sich genau wie der Begleiter verhält, aber einen Namen haben muss.
Gibt es vielleicht einen Unterschied im "statischen" Lebenszyklus (ich bin von der Java-Seite)?
object
kotlin
companion-object
Poweranimal
quelle
quelle
object
für Singletons undcompanion object
für statische Methoden. Kotlin - Objektdeklarationen bieten eine gute Erklärung für die Verwendung.Antworten:
Objekte können Schnittstellen implementieren. Innerhalb einer Klasse hat das Definieren eines einfachen Objekts, das keine Schnittstellen implementiert, in den meisten Fällen keinen Vorteil. Das Definieren mehrerer Objekte, die verschiedene Schnittstellen implementieren (z. B.
Comparator
), kann jedoch sehr nützlich sein.In Bezug auf den Lebenszyklus gibt es keinen Unterschied zwischen einem Begleitobjekt und einem in einer Klasse deklarierten benannten Objekt.
quelle
Es gibt zwei verschiedene
object
Verwendungsarten: Ausdruck und Deklaration .Objektausdruck
Ein Objektausdruck kann verwendet werden, wenn eine Klasse geringfügig geändert werden muss, es ist jedoch nicht erforderlich, eine völlig neue Unterklasse dafür zu erstellen. Anonyme innere Klassen sind ein gutes Beispiel dafür.
button.setOnClickListener(object: View.OnClickListener() { override fun onClick(view: View) { // click event } })
Eine Sache, auf die Sie achten müssen, ist, dass anonyme innere Klassen auf Variablen aus dem umschließenden Bereich zugreifen können, und diese Variablen müssen es nicht sein
final
. Dies bedeutet, dass eine Variable, die in einer anonymen inneren Klasse verwendet wird, die nicht berücksichtigt wirdfinal
, den Wert unerwartet ändern kann, bevor auf sie zugegriffen wird.Objektdeklaration
Eine Objektdeklaration ähnelt einer Variablendeklaration und kann daher nicht auf der rechten Seite einer Zuweisungsanweisung verwendet werden. Objektdeklarationen sind sehr nützlich für die Implementierung des Singleton-Musters.
object MySingletonObject { fun getInstance(): MySingletonObject { // return single instance of object } }
Und die
getInstance
Methode kann dann so aufgerufen werden.Begleitobjekt
Ein Begleitobjekt ist eine bestimmte Art von Objektdeklaration, mit der sich ein Objekt ähnlich wie statische Objekte in anderen Sprachen (z. B. Java) verhalten kann. Durch Hinzufügen
companion
zur Objektdeklaration kann einem Objekt die "statische" Funktionalität hinzugefügt werden, obwohl das eigentliche statische Konzept in Kotlin nicht vorhanden ist. Hier ist ein Beispiel für eine Klasse mit Instanzmethoden und Begleitmethoden.class MyClass { companion object MyCompanionObject { fun actsAsStatic() { // do stuff } } fun instanceMethod() { // do stuff } }
Das Aufrufen der Instanzmethode würde folgendermaßen aussehen.
var myClass = MyClass() myClass.instanceMethod()
Das Aufrufen der Companion-Objektmethode würde folgendermaßen aussehen.
Weitere Informationen finden Sie in den Kotlin-Dokumenten .
quelle
MyClass.MyCompanionObject.actsAsStatic()
oderMyClass.Companion.actsAsStatic()
wenn der Begleiter Objekt keinen Namen hat. Ist das eine neue Änderung oder habe ich etwas falsch gemacht? Vielen Dank.Ein Objekt oder eine Objektdeklaration wird beim ersten Zugriff träge initialisiert.
Ein Begleitobjekt wird initialisiert, wenn die entsprechende Klasse geladen wird. Es bewirkt die "statische" Essenz, obwohl Kotlin statische Mitglieder nicht von Natur aus unterstützt.
quelle
Wie Kotlin in Aktion feststellt
Wenn es um ein einfaches Objekt und ein Begleitobjekt geht, besteht der einzige wesentliche Unterschied darin, dass auf Eigenschaften und Funktionen eines Begleitobjekts direkt zugegriffen werden kann, indem der Name der enthaltenen Klasse verwendet wird. Das lässt es wie Java Static Member Access erscheinen.
Zum Beispiel, wenn Sie folgende Klasse haben
class Temp{ object Holder{ fun foo() = 1 } companion object{ fun foo() = "Hello World" } }
Anschließend können Sie auf beide Objekte wie folgt zugreifen: From enthält Klasse
foo() // call to companion object function Holder.foo() // call to plain object function
und von außerhalb der Klasse
Temp.foo() // call to companion object function Temp.Holder.foo() // call to plain object function
Unter der Haube erzeugt jede Objektdeklaration einen Singleton. Im Fall eines Begleitobjekts wird das Singleton-Objekt im statischen Initialisierer der enthaltenden Klasse erstellt. Bei einfachen Objekten wird die Singleton-Instanz jedoch träge erstellt, wenn zum ersten Mal auf die Objektklasse zugegriffen wird.
Sie können es selbst sehen, indem Sie die Kotlin-Klasse kompilieren und dann die generierten Klassendateien mit einem Java-Dekompiler dekompilieren.
warum es auch die Möglichkeit gibt, ein normales Objekt in der Klasse zu deklarieren. Betrachten Sie die folgende Klasse, in der das Member-Objekt sehr nützlich ist.
data class Employee(val name: String) { object NameComparator : Comparator<Employee> { override fun compare(p1: Employee, p2: Employee): Int = p1.name.compareTo(p2.name) } }
Jetzt können wir eine Liste der Mitarbeiter als sortieren
quelle
Das Companion-Objekt ist vorhanden, da Sie die Funktionen / Eigenschaften von Companion-Objekten wie eine statische Java-Methode / ein statisches Java-Feld aufrufen können. Und warum Sie
Holder
erlaubt sind, gibt es keinen Grund, warum das Deklarieren eines verschachtelten Objekts illegal ist. Es kann manchmal nützlich sein.quelle
Ein Companion-Objekt wird beim Laden der Klasse initialisiert (normalerweise beim ersten Referenzieren durch anderen Code, der ausgeführt wird), während Objektdeklarationen beim ersten Zugriff träge initialisiert werden.
Weitere Informationen finden Sie unter https://kotlinlang.org/docs/reference/object-declarations.html. Der untere Abschnitt definiert den Unterschied zwischen diesen beiden klar.
quelle