Tại sao chúng ta sử dụng đối tượng đồng hành của người dùng khác như một loại thay thế cho các trường tĩnh Java trong Kotlin?


145

Ý nghĩa dự định của "đối tượng đồng hành" là gì? Cho đến nay tôi đã sử dụng nó chỉ để thay thế Java statickhi tôi cần.

Tôi bối rối với:

  • Tại sao lại gọi là "bạn đồng hành"?
  • Có nghĩa là để tạo nhiều thuộc tính tĩnh , tôi phải nhóm nó lại với nhau trong companion objectkhối?
  • Để ngay lập tức tạo một cá thể đơn lẻ trong phạm vi một lớp, tôi thường viết

:

companion object {
    val singleton by lazy { ... }
}

có vẻ như là một cách làm khác thường Cách tốt hơn là gì?

Câu trả lời:


108
  • Ý nghĩa dự định của "đối tượng đồng hành" là gì? Tại sao lại gọi là "bạn đồng hành"?

    Đầu tiên, Kotlin không sử dụng khái niệm staticthành viên Java vì Kotlin có khái niệm objects riêng để mô tả các thuộc tính và hàm được kết nối với trạng thái singleton và staticphần Java của một lớp có thể được biểu thị một cách thanh lịch theo thuật ngữ của singleton: đó là một đối tượng đơn lẻ có thể được gọi bằng tên của lớp. Do đó, việc đặt tên: đó là một đối tượng đi kèm với một lớp.

    Tên của nó được sử dụng class objectdefault object , nhưng sau đó nó được đổi tên thànhcompanion object rõ ràng hơn và cũng phù hợp với các đối tượng đồng hành Scala .

    Ngoài việc đặt tên, nó còn mạnh hơn các staticthành viên Java : nó có thể mở rộng các lớp và giao diện, và bạn có thể tham chiếu và chuyển nó xung quanh giống như các đối tượng khác.

  • Có nghĩa là để tạo nhiều thuộc tính tĩnh, tôi phải nhóm nó lại với nhau trong companion objectkhối?

    Vâng, đó là cách thành ngữ. Hoặc thậm chí bạn có thể nhóm chúng trong các đối tượng không đồng hành theo ý nghĩa của chúng:

    class MyClass {
        object IO {
            fun makeSomethingWithIO() { /* ... */ }
        }
    
        object Factory {
            fun createSomething() { /* ... */ }
        }
    }
  • Để ngay lập tức tạo một cá thể đơn lẻ được sắp xếp trong một lớp, tôi thường viết /*...*/nó có vẻ như là một cách làm khác thường. Cách tốt hơn là gì?

    Nó phụ thuộc vào những gì bạn cần trong từng trường hợp cụ thể. Mã của bạn rất phù hợp để lưu trữ trạng thái ràng buộc với một lớp được khởi tạo khi gọi lần đầu tiên đến nó.

    Nếu bạn không cần nó được kết nối với một lớp, chỉ cần sử dụng khai báo đối tượng:

    object Foo {
        val something by lazy { ... }
    }

    Bạn cũng có thể xóa lazy { ... }ủy quyền để khởi tạo thuộc tính khi sử dụng lớp đầu tiên, giống như các trình khởi tạo tĩnh Java

    Bạn cũng có thể tìm thấy những cách hữu ích để khởi tạo trạng thái singleton .


Ví dụ đẹp và thành ngữ.
Trein

19

Tại sao lại gọi là "bạn đồng hành"?

Đối tượng này là bạn đồng hành của các trường hợp. IIRC đã có cuộc thảo luận dài ở đây: sắp tới-thay đổi-đối tượng-suy nghĩ lại

Có nghĩa là để tạo nhiều thuộc tính tĩnh, tôi phải nhóm nó lại với nhau trong khối đối tượng đồng hành?

Đúng. Mọi thuộc tính / phương thức "tĩnh" cần được đặt bên trong người bạn đồng hành này.

Để ngay lập tức tạo một cá thể đơn lẻ trong phạm vi một lớp, tôi thường viết

Bạn không tạo cá thể singleton ngay lập tức. Nó được tạo ra khi truy cập singletonlần đầu tiên.

có vẻ như là một cách làm khác thường Cách tốt hơn là gì?

Thay vì đi với object Singleton { } để xác định một lớp đơn. Xem: Khai báo đối tượng Bạn không phải tạo một thể hiện Singleton, chỉ cần sử dụng nó như thếSingleton.doWork()

Chỉ cần nhớ rằng Kotlin cung cấp các công cụ khác để tổ chức mã của bạn. Hiện tại có các lựa chọn thay thế cho các hàm tĩnh đơn giản, ví dụ: bạn có thể sử dụng Hàm cấp cao nhất thay thế.


7

Tại sao lại gọi là "bạn đồng hành"?

Một khai báo đối tượng bên trong một lớp có thể được đánh dấu bằng từ khóa đồng hành:

class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

Các thành viên của đối tượng đồng hành có thể được gọi bằng cách sử dụng tên lớp đơn giản là vòng loại:

val instance = MyClass.create()

Nếu bạn chỉ sử dụng 'đối tượng' mà không có 'bạn đồng hành', bạn phải làm như thế này:

val instance = MyClass.Factory.create()

Theo hiểu biết của tôi, 'bạn đồng hành' có nghĩa là đối tượng này là bạn đồng hành với lớp người ngoài.


"đối tượng" không có "bạn đồng hành" được gọi như thế này (MyClass (). created ()). Giống như một singleton, nhưng để truy cập vào đối tượng singleton, trước tiên bạn phải khởi tạo lớp "bên ngoài".
LiTTle

0

Chúng ta có thể nói rằng đồng hành giống như "Khối tĩnh" như Java, nhưng trong trường hợp của Kotlin, không có khái niệm Khối tĩnh, hơn là đồng hành đi vào khung.

Cách xác định khối đồng hành:

class Example {
      companion object {
        fun display(){
        //place your code
     }
  }
}

Phương thức gọi của khối đồng hành, trực tiếp với tên lớp

Example.Companion.display
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.