Cómo imitar o lograr relaciones IS-A para las classs de datos de Kotlin
He estado explorando Kotlin y he escrito un pequeño progtwig / script que hace una tarea que me resulta aburrida.
En el desarrollo del progtwig utilizo classs de datos para representar una list de reproducción. En un punto del layout, quería tener un tipo especial de Playlist
que fuera EmptyPlaylist
.
- ¿Dónde intelliJ pone kotlin.js en un proyecto multiplataforma?
- ¿Cómo trabajar con foldRight () en Kotlin?
- Cómo alternar la visibilidad de FAB con otro FAB
- ¿Es posible usar Mockito en Kotlin?
- Room y Kotlin: get "Cada variable de vinculación en la consulta debe tener un parámetro de método coincidente".
No pude hacer que esto funcione.
¿Cómo lograría esta relación con Kotlin?
En Java, simplemente extendería la Playlist
(o tal vez crearía una class de interfaz / resumen para que henetworkingen ambos).
Solo quería poder tener una List<Playlist>
lugar de List<Playlist?>
Al final, acabo de crear un object Playlist
, pero estoy interesado en si es posible crear jerarquías IS-A con classs de datos.
- ¿Tenemos que aprender java primero para aprender kotlin o puedo comenzarlo directamente?
- cómo hacer clic en el enlace de URL en TextView en Android sin usar java
- Declaraciones de class en Kotlin
- Cuál es la diferencia entre la class normal y la class de datos en kotlin
- Sobrecarga de setter en Kotlin
- ¿Cómo save una reference de function como el valor en un tipo de Mapa e invocarlo con un parámetro más adelante en Kotlin?
- Simplificación de obtención de propiedad a través de delegación
- Cómo arreglar "La característica no es parte del esquema para este Reino" en Kotlin Realm Extention
UPD: Kotlin Beta agregó restricciones en data
classs de data
, por lo que la respuesta también se ha actualizado.
- Las classs de datos no pueden ser abstractas, abiertas, selladas o internas;
- Las classs de datos no pueden extender otras classs (pero pueden implementar interfaces).
Entonces, la única opción para build sus jerarquías son las interfaces. Esta restricción puede ser lanzada en futuras versiones.
La idea de henetworkingar
EmptyPlaylist
de Playlist
que se presume no está vacía de acuerdo con tus palabras parece un poco contradictoria, pero hay opciones:
-
Puede hacer que tanto
TracksPlaylist
comoEmptyPlaylist
implementen una interfazPlaylist
. Esto es razonable porqueEmptyPlaylist
puede no contener todo lo que hace unaPlaylist
. Esto se vería así:public interface Playlist data class TracksPlaylist(val name: String, val tracks: List<Track>) : Playlist data class EmptyPlaylist(val name: String): Playlist
-
Si no quiere que incluso existan varias instancias de
EmptyPlaylist
, puede convertirlo enval
lugar de en class distinta y evitar is-checks, simplemente comparando conval EMPTY_PLAYLIST = TracksPlaylist("EMPTY", listOf())
Esto es aplicable cuando las lists de reproducción vacías son todas iguales, por lo que un solo object es suficiente para representarlas todas.
-
Puedes usar classs
sealed
. Esto no le permite usar classs dedata
, pero las classssealed
pueden ajustarse para build jerarquías de classs como esta.class
sealed
es una class abstracta que solo puede tener sus subclasss declaradas dentro de su cuerpo. Esto le da al comstackdor garantías de que estas son las únicas subclasss. Ejemplo:sealed class Playlist(val name: String) { class Tracks(name: String, val tracks: List<Track>): Playlist(name) class Playlists(name: String, val innerPlaylists: List<Playlist>): Playlist(name) object Empty: Playlist("EMPTY") }
Después de eso, podrá usar la instrucción
when
sin especificar la twigelse
si declara todas las subclasss y objects de la class sellada:when (p) { is Playlist.Tracks -> { /* ... */ } is Playlist.Playlists -> { /* ... */ } Playlist.Empty -> { /* ... */ } }
Sin embargo, esta opción requiere que se ocupe de
equals
,hashCode
,toString
,copy
ycomponentN
por su count, si los necesita.