코 틀린에서 데이터 클래스 확장
데이터 클래스는 Java의 구식 POJO를 대체하는 것으로 보입니다. 이러한 클래스가 상속을 허용 할 것으로 예상되지만 데이터 클래스를 확장하는 편리한 방법은 없습니다. 내가 필요한 것은 다음과 같습니다.
open data class Resource (var id: Long = 0, var location: String = "")
data class Book (var isbn: String) : Resource()
component1()
메소드 의 충돌로 인해 위의 코드가 실패 합니다. data
클래스 중 하나에 만 주석을 남겨두면 작동하지 않습니다.
아마도 데이터 클래스를 확장하는 또 다른 관용구가 있습니까?
UPD : 자식 자식 클래스에만 주석을 달 수 있지만 data
주석은 생성자에서 선언 된 속성 만 처리합니다. 즉, 모든 부모의 속성을 선언 open
하고 무시해야합니다.
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()
진실은 데이터 클래스가 상속과 잘 어울리지 않는다는 것입니다. 데이터 클래스의 상속을 금지하거나 심각하게 제한하는 것을 고려하고 있습니다. 예를 들어, equals()
비추 상 클래스의 계층 구조에서 올바르게 구현할 수있는 방법이없는 것으로 알려져 있습니다.
따라서 내가 제공 할 수있는 모든 것 : 데이터 클래스에 상속을 사용하지 마십시오.
생성자 외부의 수퍼 클래스에서 속성을 추상으로 선언하고 하위 클래스에서 재정의합니다.
abstract class Resource {
abstract var id: Long
abstract var location: String
}
data class Book (
override var id: Long = 0,
override var location: String = "",
var isbn: String
) : Resource()
위의 추상 클래스를 사용하는 솔루션은 실제로 해당 클래스를 생성하고 데이터 클래스를 확장시킵니다.
추상 클래스를 원하지 않으면 인터페이스 를 사용하는 것이 어떻습니까?
Kotlin의 인터페이스는 이 기사에 표시된대로 속성 을 가질 수 있습니다 .
interface History {
val date: LocalDateTime
val name: String
val value: Int
}
data class FixedHistory(override val date: LocalDateTime,
override val name: String,
override val value: Int,
val fixedEvent: String) : History
Kotlin이 이것을 어떻게 컴파일하는지 궁금했습니다. Intellij [Kotlin bytecode] 기능을 사용하여 생성 된 동등한 Java 코드는 다음과 같습니다.
public interface History {
@NotNull
LocalDateTime getDate();
@NotNull
String getName();
int getValue();
}
public final class FixedHistory implements History {
@NotNull
private final LocalDateTime date;
@NotNull
private final String name;
private int value;
@NotNull
private final String fixedEvent;
// Boring getters/setters as usual..
// copy(), toString(), equals(), hashCode(), ...
}
보시다시피, 일반 데이터 클래스와 똑같이 작동합니다!
@ Željko Trogrlić의 답변이 정확합니다. 그러나 추상 클래스에서와 동일한 필드를 반복해야합니다.
또한 추상 클래스 내에 추상 서브 클래스가있는 경우 데이터 클래스에서 이러한 추상 서브 클래스에서 필드를 확장 할 수 없습니다. 먼저 데이터 서브 클래스 를 만든 다음 필드를 정의해야합니다.
abstract class AbstractClass {
abstract val code: Int
abstract val url: String?
abstract val errors: Errors?
abstract class Errors {
abstract val messages: List<String>?
}
}
data class History(
val data: String?,
override val code: Int,
override val url: String?,
// Do not extend from AbstractClass.Errors here, but Kotlin allows it.
override val errors: Errors?
) : AbstractClass() {
// Extend a data class here, then you can use it for 'errors' field.
data class Errors(
override val messages: List<String>?
) : AbstractClass.Errors()
}
비 데이터 클래스에서 데이터 클래스를 상속 할 수 있습니다. 상속시 컴파일러 생성 데이터 클래스 메소드를 일관되고 직관적으로 작동시킬 수있는 방법이 없으므로 다른 데이터 클래스에서 데이터 클래스를 상속 할 수 없습니다.
코 틀린 특성이 도움이 될 수 있습니다.
interface IBase {
val prop:String
}
interface IDerived : IBase {
val derived_prop:String
}
데이터 클래스
data class Base(override val prop:String) : IBase
data class Derived(override val derived_prop:String,
private val base:IBase) : IDerived, IBase by base
샘플 사용법
val b = Base("base")
val d = Derived("derived", b)
print(d.prop) //prints "base", accessing base class property
print(d.derived_prop) //prints "derived"
This approach can also be a workaround for inheritance issues with @Parcelize
@Parcelize
data class Base(override val prop:Any) : IBase, Parcelable
@Parcelize // works fine
data class Derived(override val derived_prop:Any,
private val base:IBase) : IBase by base, IDerived, Parcelable
You can inherit a data class from a non-data class.
Base class
open class BaseEntity (
@ColumnInfo(name = "name") var name: String? = null,
@ColumnInfo(name = "description") var description: String? = null,
// ...
)
child class
@Entity(tableName = "items", indices = [Index(value = ["item_id"])])
data class CustomEntity(
@PrimaryKey
@ColumnInfo(name = "id") var id: Long? = null,
@ColumnInfo(name = "item_id") var itemId: Long = 0,
@ColumnInfo(name = "item_color") var color: Int? = null
) : BaseEntity()
It worked.
참고URL : https://stackoverflow.com/questions/26444145/extend-data-class-in-kotlin
'IT story' 카테고리의 다른 글
Xcode 8.3.3“iTunes Connect 액세스 권한이있는 계정이 없습니다” (0) | 2020.06.29 |
---|---|
자바 스크립트 파일을 동적으로로드하는 JQuery (0) | 2020.06.29 |
Angular 지시문에서 데이터 변경 사항을 감시합니다. (0) | 2020.06.29 |
대용량 데이터에서 NA를 대체하는 가장 빠른 방법 (0) | 2020.06.29 |
내용이 넘치면 스크롤 해야하는 고정 위치 div가 있어야합니다. (0) | 2020.06.29 |