gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 13:24:18 24 4
gpt4 key购买 nike

在Java中,

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();
}
}

在 Kotlin ,这可以归结为:

方法1:
sealed class NumericValueA{
abstract var a: String
abstract var b: String
}

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

方法二:
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是否为最新技术”。

internal abstract class NumericValue {
var a: String? = null
var b: String? = null

override fun equals(o: Any?): Boolean {
if (this === o) return true
if (o == null || javaClass != o.javaClass) return false

val that = o as NumericValue?

if (if (a != null) a != that!!.a else that!!.a != null) return false
return if (b != null) b == that.b else that.b == null
}

override fun hashCode(): Int {
var result = if (a != null) a!!.hashCode() else 0
result = 31 * result + if (b != null) b!!.hashCode() else 0
return result
}
}

internal class Abc : NumericValue() {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val abc = Abc()
abc.a
}
}
}

但是,您的问题专门针对“数据”类。数据类是语言的一个很好的组成部分,它为我们提供了“解构”功能以及一些有用的自动生成的解构方法(例如 componentN)。因此,使用上面的代码(并在类中添加 open以及 ab的声明),此处的示例派生类的实现略有不同。
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)
}
}
}

这似乎是合理的,因为您的初始示例不是数据类,而您的明显愿望是使用Kotlin数据类。它为您提供了理想的功能(如果需要),但付出了更多的代码细节。

如果将基声明为 sealeda以及 b作为 abstract,则派生类是相同的代码。

因此,对于数据类, 是您想要在派生类中公开为“数据”的基类的任何部分的重复(已经公开,只是不作为“数据类”的特殊成员公开,例如如以下示例所示)。但这类似于在其他上下文中的覆盖。只是想一想,现在考虑以下派生类。
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
}
}
}

您将获得基类的所有成员以及派生类的新数据成员。但是,如果您想获得优先利益,那么它又会花费一些句法语言(对于派生数据类和常规类)。

最后一点。数据类还具有其他与继承性和替代有关的怪异现象,可能仍需要解决。 toStringhashCodeequals获得自己的特殊实现,并且 documentation说...

If there are explicit implementations of equals(), hashCode() or toString() in the data class body or final implementations in a superclass, then these functions are not generated, and the existing implementations are used;



...我觉得难以理解(导致我尝试而不是依赖文档)。还有其他关于 toString和数据类的争执的SO问题(例如: this OP trying to create a DTO)。

所以,我认为这是最新技术,而且还不错(IMO)。是的,如果您想要数据类的功能,则可以像完成操作一样对其进行转换。

关于inheritance - 如何对数据类使用简单继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46184161/

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