As classes de dados parecem substituir os POJOs à moda antiga em Java. É bastante esperado que essas classes permitam herança, mas não vejo uma maneira conveniente de estender uma classe de dados. O que eu preciso é algo como isto:
open data class Resource (var id: Long = 0, var location: String = "")
data class Book (var isbn: String) : Resource()
O código acima falha devido a conflito de component1()
métodos. Deixar a data
anotação em apenas uma das classes também não funciona.
Talvez haja outro idioma para estender as classes de dados?
UPD: Eu posso anotar apenas classe filho filho, mas a data
anotação trata apenas das propriedades declaradas no construtor. Ou seja, eu teria que declarar todas as propriedades dos pais open
e substituí-las, o que é feio:
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
fonte
fonte
componentN()
que retornam valor da N-ésima propriedade. Veja documentos sobre Multi-DeclaraçõesRespostas:
A verdade é: as classes de dados não funcionam muito bem com herança. Estamos pensando em proibir ou restringir severamente a herança de classes de dados. Por exemplo, sabe-se que não há como implementar
equals()
corretamente em uma hierarquia em classes não abstratas.Então, tudo o que posso oferecer: não use herança com classes de dados.
fonte
Declare propriedades na superclasse fora do construtor como abstratas e substitua-as na subclasse.
fonte
Type Mismatch
erro: "T necessário, encontrado: recurso". Você pode me dizer como ele pode ser usado em genéricos?Location(long: Double, lat: Double))
em outro?A solução acima, usando a classe abstrata, na verdade gera a classe correspondente e permite que a classe de dados se estenda a partir dela.
Se você não prefere classe abstrata, que tal usar uma interface ?
A interface no Kotlin pode ter propriedades, como mostrado neste artigo .
Fiquei curioso para saber como Kotlin compila isso. Aqui está o código Java equivalente (gerado usando o recurso Intellij [Kotlin bytecode]):
Como você pode ver, ele funciona exatamente como uma classe de dados normal!
fonte
@ Eljko Trogrlić resposta está correta. Mas temos que repetir os mesmos campos que em uma classe abstrata.
Além disso, se tivermos subclasses abstratas dentro da classe abstrata, em uma classe de dados não poderemos estender os campos dessas subclasses abstratas. Primeiro devemos criar subclasse de dados e depois definir campos.
fonte
Traços de Kotlin podem ajudar.
classes de dados
uso de amostra
Essa abordagem também pode ser uma solução alternativa para problemas de herança com o @Parcelize
fonte
Você pode herdar uma classe de dados de uma classe que não é de dados. A herança de uma classe de dados de outra classe de dados não é permitida porque não há como fazer com que os métodos de classe de dados gerados pelo compilador funcionem de maneira consistente e intuitiva em caso de herança.
fonte
Embora a implementação
equals()
correta em uma hierarquia seja realmente um problema, ainda seria bom dar suporte à herança de outros métodos, por exemplo:toString()
.Para ser um pouco mais concreto, vamos assumir que temos a seguinte construção (obviamente, não funciona porque
toString()
não é herdada, mas não seria bom se funcionasse?):Supondo que o nosso
User
eLocation
entidades devolver os seus IDs de recursos apropriados (UserResourceId
eLocationResourceId
respectivamente), chamandotoString()
em qualquerResourceId
poderia resultar em muito uma representação pouco agradável que é geralmente válido para todos os subtipos:/users/4587
,/locations/23
, etc. Infelizmente, porque não dos subtipos herdada para substituídotoString()
método do base abstrataResourceId
, chamandotoString()
realmente resulta em uma representação menos bonita:<UserResourceId(id=UserId(value=4587))>
,<LocationResourceId(id=LocationId(value=23))>
Existem outras maneiras de modelar o exposto acima, mas elas nos forçam a usar não-classes de dados (perdendo muitos dos benefícios das classes de dados) ou acabamos copiando / repetindo a
toString()
implementação em todas as nossas classes de dados (sem herança).fonte
Você pode herdar uma classe de dados de uma classe que não é de dados.
Classe base
classe infantil
Funcionou.
fonte