2016-06-24 21 views
11

Tôi đã viết các phương pháp này trong Kotlin và phân tích các bytecode:Kotlin đối tượng vs bạn đồng hành đối tượng vs gói scoped phương pháp

Tình hình 1

class A { 
    object b { 
     fun doSomething() {} 
    } 
} 

Tình hình 2

class A { 
    companion object b { 
     fun doSomething() {} 
    } 
} 

Tình huống 3

fun doSomething() {} 

Bytecode quả

  • Trường hợp 1: lớp Test$asb, public final doSomething()I
  • Trường hợp 2: lớp Test$Companion, public final doSomething()I
  • Tình huống 3: lớp TestKt, public final static doSomething()I

Câu hỏi của tôi là:

  • Tôi có một lớp enum, và tôi muốn trả về một instum enum cho một biến enum, ví dụ, findById (enum(id, color)). Tôi sẽ làm như thế nào? Đối tượng đồng hành? vật?

  • Có vẻ như cách duy nhất để có phương thức tĩnh thực sự là ở cấp gói, không có khai báo lớp. Nhưng điều đó trở nên quá toàn cầu. Có cách nào để truy cập thông qua: ClassName.staticMethod, staticMethod thực sự tĩnh hay không.

  • Cung cấp các ví dụ đầy đủ về các phương pháp khai báo gói, đối tượng và đối tượng đồng hành.

Bối cảnh. Tôi đã được mã hóa trong Kotlin và tôi thấy nó tuyệt vời. Nhưng đôi khi tôi cần phải đưa ra quyết định: ví dụ, một tài sản bất biến nặng mà trong java tôi sẽ khai báo là tĩnh cuối cùng, nhưng trong Kotlin tôi thấy khó để "tìm thấy một tương đương".

+0

Có lẽ điều này có thể trợ giúp {http://stackoverflow.com/q/37794850/2804610} – EPadronU

+0

Trong rega rds cho đoạn cuối của bạn, tôi nghĩ rằng câu trả lời này có thể giúp bạn {http://stackoverflow.com/a/37944990/2804610} – EPadronU

Trả lời

3

tôi sẽ đề nghị để phát triển voddan answer:

enum class Color { 

    RED, 
    BLUE, 
    GREEN; 


    companion object Utils { 
     fun findById(color: Color): Color { 
      return color; 
     } 
    } 
} 

Và để kiểm tra

@Test 
fun testColor() { 
    println(Color.Utils.findById(Color.valueOf("RED"))); 
} 
+3

Tại sao không gọi trực tiếp từ lớp 'Color'? 'println (Color.findById (Color.valueOf (" RED ")));' – UnKnown

8

Nếu bạn có một hàm thực hiện một số hành động liên quan chặt chẽ đến một lớp nhưng không yêu cầu cá thể lớp, chẳng hạn như ví dụ findById, bạn nên đặt nó vào đối tượng đồng hành của lớp.

Nếu bạn muốn hiển thị phương thức dưới dạng phương thức tĩnh cho mã Java, bạn có thể chú thích phương thức đó bằng chú thích @JvmStatic.

5

Nếu một hàm không yêu cầu một thể hiện của một lớp, thì đó là quyết định thiết kế của bạn để đặt nó ở đâu. Sử dụng mức gói nếu nó là gói cụ thể, sử dụng một lớp đồng hành nếu nó relets chặt chẽ với lớp (ví dụ các lớp khác trong gói có chức năng tương tự).

Lưu ý rằng enum có một số thuộc tính trong xây dựng và các mẫu:

enum class Colour(val value: Int) { 
    black(100), red(200), green(300) 
} 

fun colourById(id: Int) = Colour.values[id] 
fun colourByValue(value: Int) = Colour.values.first {it.value == value} 
fun colourByName(name: String) = Colour.valueOf(name) 
Các vấn đề liên quan