Inheritance 如何对数据类使用简单继承?

Inheritance 如何对数据类使用简单继承?,inheritance,kotlin,data-class,Inheritance,Kotlin,Data Class,在爪哇 abstract class NumericValue{ private String a; private String b; public String getA() { return a; } public void setA(String a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b;

在爪哇

abstract class NumericValue{
    private String a;
    private String b;

    public String getA() { return a; }

    public void setA(String a) { this.a = a; }

    public String getB() { return b; }

    public void setB(String b) { this.b = b; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        NumericValue that = (NumericValue) o;

        if (a != null ? !a.equals(that.a) : that.a != null) return false;
        return b != null ? b.equals(that.b) : that.b == null;
    }

    @Override
    public int hashCode() {
        int result = a != null ? a.hashCode() : 0;
        result = 31 * result + (b != null ? b.hashCode() : 0);
        return result;
    }
}

class Abc extends NumericValue{
    public static void main(String[] args) {
        Abc abc = new Abc();
        abc.getA();
    }
}
在科特林,这归结为:

方法1:

sealed class NumericValueA{
    abstract var a: String
    abstract var b: String
}

data class AbcA(
        override var a:String,
        override var b:String
):NumericValueA()
方法2:

open class NumericValueB(
        open var a:String,
        open var b:String
)

data class AbcB(
        override var a:String,
        override var b:String
):NumericValueB(a,b)
当数据类只是继承属性时,这两种方法都倾向于大量重复,因为您必须再次写下指定的所有内容——这根本无法扩展,而且感觉有些错误


这是最先进的技术,还是这真的是将以前的java代码翻译成kotlin的最佳方法?

IntelliJ Idea将您的java代码翻译成以下内容,这似乎是合理的,并且简化了。所以,我会回答,“不,你们的前提不能准确地描述科特林是否是最先进的”

这似乎是合理的,因为您的起始示例不是一个数据类,您显然希望使用Kotlin数据类。它为您提供了一个理想的特性(如果您需要的话),但代价是增加了一点代码冗余

如果将基类声明为
sealed
a
b
abstract
,则派生类是相同的代码

因此,在数据类的情况下,存在要在派生类中作为“数据”公开的基类的任何部分的复制(它已经公开,而不是作为“数据类”特殊成员,如下面的示例所示)。但这类似于其他上下文中的覆盖。只是为了思考,现在考虑下面的派生类。

internal data class AbcB (override var a: String?, override var b: String?) : NumericValue() {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            val abc = AbcB("a","b")
            println("b = " + abc.component2())
            val n: NumericValue = abc
            println("a = " + n.a)
        }
    }
}
internal data class AbcCD (var c: String?, var d: String?) : NumericValue() {
    companion object {
        @JvmStatic
        fun x() {
            val abc = AbcCD("c","d")
            abc.b = "B"
            abc.a = "A"
            println("d = " + abc.component2())
            abc.a
        }
    }
}
您将获得基类的所有成员以及派生类的新数据成员。但是,如果您想要覆盖优点,那么它同样需要一些语法冗余(对于派生数据类和常规类)

最后一点。数据类仍然有其他与继承和重写相关的奇怪之处,这些可能仍然需要解决
toString
hashCode
equals
都有自己的特殊实现,并表示

如果在数据类主体中存在equals()、hashCode()或toString()的显式实现,或者在超类中存在最终实现,则不会生成这些函数,而是使用现有实现

。。。我发现读起来很困惑(导致我进行实验,而不是依赖文档)。还有其他一些SO问题涉及到
toString
和数据类(例如:)之间的斗争


所以,我认为这是最先进的,也没那么糟糕(IMO)。是的,如果你想了解数据类的特性,你可以像以前一样翻译它。

很简单,但我的问题明确针对数据类。这是怎么翻译成这个解释的?谢谢你的详细解释!在这个过程中,我意识到我可能不需要数据类,所以我将尝试一下。。。。要进行细分,不可能消除重复杂波。对吗?但是我还不明白,如果我跳过类中的“数据”,当你说“但是如果你想要覆盖的好处,它又需要一些语法上的赘述”时,我是否可以省略重复。是的,如果你想要成员的覆盖行为,你会重复覆盖声明中的很多语法。无论是数据类还是常规类,我都无法避免它。但我编辑了我的答案,试图澄清这一点。我不知道你想做什么。我会这样翻译Java(我对格式表示歉意):
抽象类NumericValue{abstract var a:String abstract var b:String}数据类Abc(覆盖var a:String,覆盖var b:String):NumericValue()fun main(vararg args:String){val Abc=Abc(“a”,“b”)val a=Abc.a}
您对AS的自动翻译不满意吗?
internal data class AbcCD (var c: String?, var d: String?) : NumericValue() {
    companion object {
        @JvmStatic
        fun x() {
            val abc = AbcCD("c","d")
            abc.b = "B"
            abc.a = "A"
            println("d = " + abc.component2())
            abc.a
        }
    }
}