如何模仿或实现Kotlin数据类的IS-A关系
我一直在探索Kotlin,写了一个小程序/脚本来完成我觉得无聊的任务。
在程序的开发中,我使用数据类来表示播放列表。 在设计中的一个点上,我想有一个特殊types的Playlist
EmptyPlaylist
。
我无法得到这个工作。
你将如何实现与Kotlin的这种关系?
在Java中,我只是扩展Playlist
(或者可能为它们创建一个接口/抽象类来inheritance)。
我只是希望能够有一个List
而不是List
最后,我创建了一个Playlist
对象,但是我感兴趣的是可以创建带有数据类的IS-A层次结构。
UPD:Kotlin Beta增加了对data
类的限制,所以答案也被更新了。
- 数据类不能是抽象的,开放的,封闭的或内在的;
- 数据类不能扩展其他类(但可能实现接口)。
所以构建层次结构的唯一选择是接口。 未来版本中可能会发布此限制。
从Playlist
中inheritanceEmptyPlaylist
这个根据你的文字推测为非空的想法看起来有点矛盾,但是有一些选择:
-
您可以使
TracksPlaylist
和EmptyPlaylist
实现一些Playlist
界面。 这是合理的,因为EmptyPlaylist
可能不包含Playlist
所做的所有事情。 这看起来像:public interface Playlist data class TracksPlaylist(val name: String, val tracks: List
-
如果你不希望
EmptyPlaylist
多个实例存在,你可以使它成为一个val
而不是独立的类,并避免is-checks,只是比较val EMPTY_PLAYLIST = TracksPlaylist("EMPTY", listOf())
当空的播放列表全部相等时,这是适用的,以便单个对象足以代表它们全部。
-
你可以使用
sealed
类 。 这不允许你使用data
类,但是sealed
类可能适合构建这样的类层次结构。sealed
类是一个抽象类,只能在其内部声明它的子类。 这给了编译器保证这些是唯一的子类。 例:sealed class Playlist(val name: String) { class Tracks(name: String, val tracks: List
之后,
when
声明了密封类的所有子类和对象,那么您将能够使用when
语句而不指定else
分支:when (p) { is Playlist.Tracks -> { /* ... */ } is Playlist.Playlists -> { /* ... */ } Playlist.Empty -> { /* ... */ } }
但是,这个选项需要你自己处理
equals
,hashCode
,toString
,copy
和componentN
,如果你需要的话。