2017-10-19 2 views
0

Einfache Beispielklasse mit BegleitobjektWie auf Companion-Objekt von Objektinstanz in Kotlin zugreifen?

class MyClass{ 
    companion object{ 
    val test = 25 
    } 
} 

Der Wert Test kann aus durch MyClass.test zugegriffen werden, aber wie von einer Instanz von MyClass zugreifen? Wenn ich val sample = MyClass() habe, wie kann ich dann auf den Test von der Probe zugreifen? sample::class.test ist nicht korrekt .... gibt es einen Weg?

Die Frage wurde gestellt: "Warum nicht einfach MyClass.test verwenden"?

Ich bevorzuge es, die Frage zu "wie" und nicht "warum" zu halten, aber da es gefragt wurde, werde ich das "warum" versuchen. Das Gleiche könnte auch für die Methoden gelten. Warum nicht statische Funktionen in einer Klasse haben und einfach Class.function() aufrufen und das Objekt als einen der Parameter übergeben?

Berücksichtigen Sie, wenn Sie mit einem Objekt arbeiten, das als abstraktere Basisklasse übergeben wird, wobei für das Objekt, mit dem Sie arbeiten, mehrere Klassen möglich sind.

Sie könnten einen Schalter und für jede mögliche Klasse und Zugriff auf den Wert (oder Funktion) von der entsprechenden Klasse auf diese Weise, aber die Idee der Polymorphie ist, dass Sie auf Klassenattribute wie eine Methode zugreifen können (obwohl ein Funktions-Methodencode für alle Mitglieder derselben Klasse) oder ein Wert, der allen Mitgliedern der Klasse aus einer Instanz eines Objekts dieser Klasse gemeinsam ist.

Meine Lösung ist so weit, einfach das Äquivalent von MyClass zu implementieren mit Test als eine statische

public class MyClass { 
    static Integer test = 25; 
    public Integer testGetter(){ return test;} 

} 

Es gibt einfache Lösungen für diese in Java, C++, Python etc .... (Ich werde liefern code proben für jeden ist das hilft) und ich würde denken, es wird eine bessere lösung in kotlin als rückgriff auf die verwendung von Java. Das Kotlin-Companion-Objekt bietet eine Alternative (und mit Vorteilen) für das Statische für Situationen, in denen auf Klassenattribute ohne eine Objektinstanz zugegriffen wird (wie Fabriken), aber es gibt eine andere Verwendung von Static für Fälle, obwohl eine Objektinstanz dies kann verfügbar sein, ist eine statische Angabe sinnvoll, da ein einzelnes Attribut von allen Mitgliedern der Klasse gemeinsam genutzt werden kann und das Attribut nicht instanzabhängig ist.

+3

Aus Neugier, warum nutzen nicht nur 'MyClass.test'? –

+0

Das Companion-Objekt wird von allen Instanzen von MyClass gemeinsam genutzt, sodass Sie nicht unbedingt auf eine Instanz zugreifen müssen. Wie bereits erwähnt, können Sie MyClass.test von überall verwenden – RobCo

+0

Ja, Sie brauchen keine Instanz. Sie haben jedoch immer noch Anwendungsfälle, um von einer Instanz aus zu arbeiten. Betrachten Sie als Beispiel ein Objekt, das als ein Parameter übergeben wurde, der von dem Parametertyp ... abgeleitet ist und auf einen Wert aus dem Begleitobjekt des Parameters – innov8

Antwort

1

Die Probleme ist, dass während Objekteigenschaften von außerhalb der Klasse zugänglich sind, sofern sie nicht öffentlich sind, sondern Eigenschaften des Begleitobjekt nicht. Dies bedeutet, Getter (und ggf. Setter) für alle Companion-Objekteigenschaften hinzuzufügen, auf die extern von der Klasse zugegriffen werden soll.

class MyClass{ 
    companion object{ 
    val test = 25 
    } 
    var staticTest get() = test // getter for test 
} 

alle dann die für den Zugriff benötigt wird, ist ::

sample.staticTest 
2

Reflexion verwenden, können Sie über companionObject gehen:

sample::class.companionObject?.memberProperties?.find { it.name == "test" } 
+1

Danke. Das funktioniert, obwohl ich auf einen einfacheren Weg gehofft habe. Eine Funktion hinzugefügt: fun KClass .companionProp (name: String) = this.companionObject? .memberProperties? .find {it.name == name}, um es etwas einfacher zu machen. – innov8

+0

Sieht gut aus für mich – s1m0nw1

Verwandte Themen