gpt4 book ai didi

kotlin - 如何模拟或实现 Kotlin 数据类的 IS-A 关系

转载 作者:行者123 更新时间:2023-12-02 12:39:58 28 4
gpt4 key购买 nike

我一直在探索 Kotlin,并编写了一个小程序/脚本来完成我觉得无聊的任务。

在程序开发中,我使用数据类来表示播放列表。在设计中的某一时刻,我想要一种特殊类型的 Playlist那是EmptyPlaylist .

我无法让它工作。

您将如何与 Kotlin 建立这种关系?

在 Java 中,我会扩展 Playlist (或者也许为他们创建一个接口(interface)/抽象类来继承)。

我只是想拥有一个List<Playlist>而不是 List<Playlist?>
最后我创建了一个 Playlist对象,但我对是否可以使用数据类创建 IS-A 层次结构感兴趣。

最佳答案

UPD:Kotlin Beta 添加了对 data 的限制类,所以答案也已更新。

  • Data classes cannot be abstract, open, sealed or inner;
  • Data classes may not extend other classes (but may implement interfaces).


因此,构建其层次结构的唯一选择是接口(interface)。此限制可能会在 future 的版本中发布。

继承的想法 EmptyPlaylist来自 Playlist根据您的说法,这被认为是非空的看起来有点矛盾,但有一些选择:
  • 您可以同时制作 TracksPlaylistEmptyPlaylist实现一些Playlist界面。这是合理的,因为 EmptyPlaylist可能不包含 Playlist 的所有内容做。这看起来像:
    public interface Playlist

    data class TracksPlaylist(val name: String, val tracks: List<Track>) : Playlist
    data class EmptyPlaylist(val name: String): Playlist
  • 如果您不想要 EmptyPlaylist 的多个实例甚至存在,你可以使它成为 val而不是不同的类并避免 is-checks,只是比较
    val EMPTY_PLAYLIST = TracksPlaylist("EMPTY", listOf())

    这适用于空播放列表都相等的情况,因此单个对象足以代表它们。
  • 您可以使用 sealed classes .这不允许您使用 data类,但 sealed类可能适合构建这样的类层次结构。
    sealed class 是一个抽象类,只能在其主体内声明其子类。这使编译器保证这些是唯一的子类。例子:
    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")
    }

    之后,您将可以使用 when未指定 else 的语句如果您声明了密封类的所有子类和对象,则分支:
    when (p) {
    is Playlist.Tracks -> { /* ... */ }
    is Playlist.Playlists -> { /* ... */ }
    Playlist.Empty -> { /* ... */ }
    }

    但是,此选项需要您处理 equals , hashCode , toString , copycomponentN如果你需要的话,你自己。
  • 关于kotlin - 如何模拟或实现 Kotlin 数据类的 IS-A 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32151378/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com