2017-05-05 14 views
26

Sự khác nhau giữa một đối tượng và đối tượng đồng hành trong một lớp trong kotlin là gì?Kotlin: Sự khác biệt giữa đối tượng và đối tượng đồng hành trong một lớp

Ví dụ:

class MyClass { 

    object Holder { 
     //something 
    } 

    companion object { 
     //something 
    } 
} 

Tôi đã đọc rằng đối tượng đồng sẽ được sử dụng, nếu các thông số chứa/phương pháp liên quan chặt chẽ đến các lớp học.

Nhưng tại sao cũng có khả năng tuyên bố một đối tượng bình thường trong lớp học? Bởi vì nó hoạt động giống như người bạn đồng hành, nhưng nó phải có tên.

Có thể có sự khác biệt trong vòng đời "tĩnh" (tôi từ phía bên java) không?

+0

'đối tượng' cho Singletons và' đối tượng đồng hành' cho phương pháp tĩnh. [Kotlin - Tuyên bố đối tượng] (https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations) cung cấp giải thích sử dụng tốt. – ArtiomLK

Trả lời

15

Đối tượng có thể triển khai giao diện. Bên trong một lớp, xác định một đối tượng đơn giản không thực hiện bất kỳ giao diện nào cũng không có lợi ích trong hầu hết các trường hợp. Tuy nhiên, việc xác định nhiều đối tượng triển khai các giao diện khác nhau (ví dụ: Comparator) có thể rất hữu ích.

Về mặt vòng đời, không có sự khác biệt giữa đối tượng đồng hành và đối tượng được đặt tên được khai báo trong một lớp.

+0

Hoàn hảo! Cảm ơn rất nhiều vì lời giải thích của bạn! – Poweranimal

+0

AFAIK có một số khác biệt trong thứ tự khởi tạo – Ilya

+0

Sự khác biệt là gì? Tôi đoán bạn đồng hành được khởi tạo đầu tiên, bởi vì nó được gắn với lớp của nó và sau đó đối tượng được gọi? – Poweranimal

2

Đối tượng đồng hành tồn tại vì bạn có thể gọi các hàm/thuộc tính của đối tác đồng hành giống như nó là một phương thức/trường tĩnh java. Và vì lý do tại sao Holder của bạn được cho phép, tốt, không có lý do nào tuyên bố một đối tượng lồng nhau là bất hợp pháp. Nó có thể có ích đôi khi.

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

Cảm ơn Mike! Đây sẽ là câu trả lời. –

+1

Tôi đã phải sử dụng phương thức bên trong đối tượng đồng hành như 'MyClass.MyCompanionObject.actsAsStatic()' hoặc 'MyClass.Companion.actsAsStatic()' nếu đối tượng đồng hành không có tên. Đó có phải là một sự thay đổi mới, hay tôi đã làm điều gì sai? Cảm ơn. – Sup

+0

Đây phải là câu trả lời được chấp nhận – onmyway133

2

Một đối tượng hoặc khai báo đối tượng, được khởi tạo một cách lười biếng, khi được truy cập lần đầu tiên.

Một đối tượng đồng hành được khởi tạo khi lớp tương ứng được tải. Nó mang lại bản chất 'tĩnh', mặc dù Kotlin vốn không hỗ trợ các thành viên tĩnh.

Các vấn đề liên quan