Kelas data tampaknya menjadi pengganti POJO kuno di Jawa. Sangat diharapkan bahwa kelas-kelas ini akan memungkinkan untuk warisan, tetapi saya tidak bisa melihat cara yang nyaman untuk memperluas kelas data. Yang saya butuhkan adalah sesuatu seperti ini:
open data class Resource (var id: Long = 0, var location: String = "")
data class Book (var isbn: String) : Resource()
Kode di atas gagal karena component1()
metode bentrok . Meninggalkan data
anotasi hanya di satu kelas tidak akan berfungsi juga.
Mungkin ada idiom lain untuk memperpanjang kelas data?
UPD: Saya mungkin memberi anotasi hanya kelas anak anak, tetapi data
anotasi hanya menangani properti yang dideklarasikan di konstruktor. Yaitu, saya harus mendeklarasikan semua properti orangtua open
dan menimpanya, yang jelek:
open class Resource (open var id: Long = 0, open var location: String = "")
data class Book (
override var id: Long = 0,
override var location: String = "",
var isbn: String
) : Resource()
inheritance
kotlin
abstract
data-class
Dmitry
sumber
sumber
componentN()
yang mengembalikan nilai properti N-th. Lihat dokumen Multi-DeklarasiJawaban:
Yang benar adalah: kelas data tidak bermain terlalu baik dengan warisan. Kami sedang mempertimbangkan untuk melarang atau sangat membatasi pewarisan kelas data. Misalnya, diketahui bahwa tidak ada cara untuk mengimplementasikan
equals()
dengan benar dalam hierarki pada kelas non-abstrak.Jadi, yang bisa saya tawarkan: jangan gunakan warisan dengan kelas data.
sumber
Deklarasikan properti di super-class di luar konstruktor sebagai abstrak, dan timpa di sub-class.
sumber
Type Mismatch
kesalahan: "T yang Diperlukan, Ditemukan: Sumberdaya". Bisakah Anda memberi tahu saya bagaimana bisa digunakan dalam Generics?Location(long: Double, lat: Double))
lain?Solusi di atas menggunakan kelas abstrak sebenarnya menghasilkan kelas yang sesuai dan membiarkan kelas data memanjang darinya.
Jika Anda tidak suka kelas abstrak, bagaimana dengan menggunakan antarmuka ?
Antarmuka di Kotlin dapat memiliki properti seperti yang ditunjukkan dalam artikel ini ..
Saya ingin tahu bagaimana Kotlin menyusun ini. Ini kode Java yang setara (dibuat menggunakan fitur Intellij [Kotlin bytecode]):
Seperti yang Anda lihat, ini berfungsi persis seperti kelas data normal!
sumber
@ Željko Trogrlić jawabannya benar. Tetapi kita harus mengulangi bidang yang sama seperti di kelas abstrak.
Juga jika kita memiliki subclass abstrak di dalam kelas abstrak, maka dalam kelas data kita tidak bisa memperluas bidang dari subclass abstrak ini. Pertama-tama kita harus membuat subkelas data dan kemudian mendefinisikan bidang.
sumber
Ciri Kotlin dapat membantu.
kelas data
penggunaan sampel
Pendekatan ini juga bisa menjadi solusi untuk masalah pewarisan dengan @Parcelize
sumber
Anda bisa mewarisi kelas data dari kelas non-data. Mewarisi kelas data dari kelas data lain tidak diperbolehkan karena tidak ada cara untuk membuat metode kelas data kompiler yang dihasilkan bekerja secara konsisten dan intuitif jika ada warisan.
sumber
Sementara menerapkan
equals()
dengan benar dalam hirarki ini memang cukup acar, masih akan bagus untuk mendukung mewarisi metode lain, misalnya:toString()
.Untuk menjadi sedikit lebih konkret, mari kita asumsikan kita memiliki konstruk berikut (jelas, itu tidak berhasil karena
toString()
tidak diwariskan, tetapi bukankah lebih baik jika itu?):Dengan asumsi kami
User
danLocation
entitas kembali ID mereka sesuai sumber daya (UserResourceId
danLocationResourceId
masing-masing), menyerukantoString()
pada setiapResourceId
dapat mengakibatkan cukup representasi kecil yang menyenangkan yang umumnya berlaku untuk semua subtipe:/users/4587
,/locations/23
, dll Sayangnya, karena non subtipe diwariskan kepada ditimpatoString()
metode dari dasar abstrakResourceId
, memanggiltoString()
benar-benar menghasilkan representasi kurang cantik:<UserResourceId(id=UserId(value=4587))>
,<LocationResourceId(id=LocationId(value=23))>
Ada beberapa cara lain untuk memodelkan hal di atas, tetapi cara-cara itu memaksa kita untuk menggunakan kelas-kelas non-data (kehilangan banyak manfaat dari kelas data), atau kita akhirnya menyalin / mengulangi
toString()
implementasi di semua kelas data kami (tidak ada warisan).sumber
Anda bisa mewarisi kelas data dari kelas non-data.
Kelas dasar
kelas anak
Itu berhasil.
sumber