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
}
}
}