2017-05-05 28 views
26

Jaka jest różnica między obiektem a obiektem towarzyszącym w klasie w kotlinach?Kotlin: Różnica między obiektem a obiektem towarzyszącym w klasie

Przykład:

class MyClass { 

    object Holder { 
     //something 
    } 

    companion object { 
     //something 
    } 
} 

ja już przeczytać, że obiekt towarzyszący stosuje się, jeżeli zawierające parametry/metody są ściśle związane z jego klasy.

Ale dlaczego istnieje również możliwość zadeklarowania normalnego przedmiotu w klasie? Ponieważ zachowuje się dokładnie tak jak towarzysz, ale musi mieć nazwę.

Czy jest jakaś różnica w jej "statycznym" (jestem od strony Java) cyklu życia?

+0

'obiekt' dla Singletonów i' obiekt towarzyszący' dla metod statycznych. [Kotlin - Deklaracje obiektów] (https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations) zapewnia dobre objaśnienie użycia. – ArtiomLK

Odpowiedz

15

Obiekty mogą implementować interfejsy. Wewnątrz klasy definiowanie prostego obiektu, który nie implementuje żadnych interfejsów, w większości przypadków nie przynosi żadnych korzyści. Jednak bardzo przydatne może być definiowanie wielu obiektów implementujących różne interfejsy (na przykład Comparator).

Pod względem cyklu życia nie ma różnicy między obiektem towarzyszącym a obiektem nazwanym zadeklarowanym w klasie.

+0

Idealny! Wielkie dzięki za wyjaśnienie! – Poweranimal

+0

AFAIK Występuje pewna różnica w zamówieniu inicjującym – Ilya

+0

Czym się różnią? Domyślam się, że kompan jest inicjowany jako pierwszy, ponieważ jest powiązany z klasą, a potem nazywa się obiekt? – Poweranimal

2

Obiekt towarzysza istnieje, ponieważ można wywoływać funkcje/właściwości obiektów towarzyszących, ponieważ jest to statyczna metoda/pole języka Java. I dlatego, że twój Holder jest dozwolony, cóż, nie ma powodu, że deklarowanie zagnieżdżonego obiektu jest nielegalne. Czasami może się przydać.

11
There are two different types of `object` uses, **expression** and **declaration**. 

**Object Expression** 

An object expression can be used when a class needs slight modification, but it's not necessary to create an entirely new subclass for it. Anonymous inner classes are a good example of this. 

    button.setOnClickListener(object: View.OnClickListener() { 
     override fun onClick(view: View) { 
      // click event 
     } 
    }) 

One thing to watch out for is that anonymous inner classes can access variables from the enclosing scope, and these variables do not have to be `final`. This means that a variable used inside an anonymous inner class that is not considered `final` can change value unexpectedly before it is accessed. 

**Object Declaration** 

An object declaration is similar to a variable declaration and therefore cannot be used on the right side of an assignment statement. Object declarations are very useful for implementing the Singleton pattern. 

    object MySingletonObject { 
     fun getInstance(): MySingletonObject { 
      // return single instance of object 
     } 
    } 

And the `getInstance` method can then be invoked like this. 

    MySingletonObject.getInstance() 

**Companion Object** 

A companion object is a specific type of object declaration that allows an object to act similar to static objects in other languages (such as Java). Adding `companion` to the object declaration allows for adding the "static" functionality to an object even though the actual static concept does not exist in Kotlin. Here's an example of a class with instance methods and companion methods. 

class MyClass { 
     companion object MyCompanionObject { 
      fun actsAsStatic() { 
       // do stuff 
      } 
     } 

     fun instanceMethod() { 
      // do stuff 
     } 
    } 

Invoking the instance method would look like this. 

    var myClass = MyClass() 
    myClass.instanceMethod() 

Invoking the companion object method would look like this. 

    MyClass.actsAsStatic() 


See the [Kotlin docs](https://kotlinlang.org/docs/reference/object-declarations.html) for more info. 
+1

Dzięki Mike! To powinna być odpowiedź. –

+1

Musiałem użyć metody wewnątrz obiektu towarzyszącego jako 'MyClass.MyCompanionObject.actsAsStatic()' lub 'MyClass.Companion.actsAsStatic()', jeśli obiekt towarzyszący nie miał nazwy. Czy to jest nowa zmiana, czy też zrobiłem coś złego? Dzięki. – Sup

+0

To powinna być zaakceptowana odpowiedź – onmyway133

2

Obiekt lub deklaracja obiektu jest inicjowana leniwie, gdy uzyskuje się do niego dostęp po raz pierwszy.

Obiekt towarzyszący jest inicjowany po załadowaniu odpowiedniej klasy. Powoduje to "statyczną" esencję, chociaż Kotlin z natury nie obsługuje statycznych członków.