英文:
Classes common behavior + immutability in Kotlin
问题
以下是您提供的代码的翻译部分:
有没有一种更不可变的方式来实现以下内容?
抽象类 Abstract {
    抽象属性 general1: String
    抽象属性 counter: Int // 不想在这里使用 var
    fun sumCounter(value: Int) {
        counter += value
    }
}
数据类 A (
    val a1: String,
    覆盖属性 general1: String,
    覆盖属性 counter: Int = 0,
): Abstract()
数据类 B (
    val b1: String,
    val b2: String,
    覆盖属性 general1: String,
    覆盖属性 counter: Int = 1,
): Abstract()
fun <T : Abstract> doSomething(obj: T) {
    //...
    obj.sumCounter(10) // 我想要:val newObj = obj.sumCounter(10)
    println(obj) // A(a1=a1, general1=general1, counter=10)
                 // B(b1=b1, b2=b2, general1=general1, counter=11)
    //...
}
fun myMain() {
    val a = A("a1", "general1")
    doSomething(a)
    val b = B("b1", "b2", "general1")
    doSomething(b)
}
请注意,代码中包含一些HTML编码字符(例如 < 和 "),这些字符可能需要根据您的需求进一步处理。如果您有其他问题或需要进一步的帮助,请告诉我。
英文:
Is there a way to achieve the following but in a more immutable way?
abstract class Abstract {
    abstract val general1: String
    abstract var counter: Int // Don't want to use var here
    fun sumCounter(value: Int) {
        counter += value
    }
}
data class A (
    val a1: String,
    override val general1: String,
    override var counter: Int = 0,
): Abstract()
data class B (
    val b1: String,
    val b2: String,
    override val general1: String,
    override var counter: Int = 1,
): Abstract()
fun <T : Abstract> doSomething(obj: T) {
    //...
    obj.sumCounter(10) // I want: val newObj = obj.sumCounter(10)
    println(obj) // A(a1=a1, general1=general1, counter=10)
                 // B(b1=b1, b2=b2, general1=general1, counter=11)
    //...
}
fun myMain() {
    val a = A("a1", "general1")
    doSomething(a)
    val b = B("b1", "b2", "general1")
    doSomething(b)
}
It could be some Kotlin trick, functional approach, or design pattern to avoid creating the same methods in A and B. But I don't want to use reflections or convert to json and back.
答案1
得分: 2
这是我能找到的最接近的内容:
这是我能找到的最接近的内容:
接口 Abstract<out T: Abstract<T>> {
    val general1: String
    val counter: Int // 不想在这里使用 var
    fun copy(newCounter: Int): T
    fun sumCounter(value: Int): T = copy(newCounter = counter + value)
}
数据类 A (
    val a1: String,
    override val general1: String,
    override val counter: Int = 0,
): Abstract<A> {
    override fun copy(newCounter: Int): A = copy(counter = newCounter)
}
数据类 B (
    val b1: String,
    val b2: String,
    override val general1: String,
    override val counter: Int = 1,
): Abstract<B> {
    override fun copy(newCounter: Int): B = copy(counter = newCounter)
}
fun <T : Abstract<T>> doSomething(obj: T) {
    //...
    val newObj = obj.sumCounter(10)
    println(newObj) // A(a1=a1, general1=general1, counter=10)
    // B(b1=b1, b2=b2, general1=general1, counter=11)
    //...
}
fun main(args: Array<String>) {
    val a = A("a1", "general1")
    doSomething(a)
    val b = B("b1", "b2", "general1")
    doSomething(b)
}
您仍然需要将 copy() 方法复制到每个子类中。
英文:
This is, unfortunately, the closest I got:
interface Abstract<out T: Abstract<T>> {
    val general1: String
    val counter: Int // Don't want to use var here
    fun copy(newCounter: Int): T
    fun sumCounter(value: Int): T = copy(newCounter = counter + value)
}
data class A (
    val a1: String,
    override val general1: String,
    override val counter: Int = 0,
): Abstract<A> {
    override fun copy(newCounter: Int): A = copy(counter = newCounter)
}
data class B (
    val b1: String,
    val b2: String,
    override val general1: String,
    override val counter: Int = 1,
): Abstract<B> {
    override fun copy(newCounter: Int): B = copy(counter = newCounter)
}
fun <T : Abstract<T>> doSomething(obj: T) {
    //...
    val newObj = obj.sumCounter(10)
    println(newObj) // A(a1=a1, general1=general1, counter=10)
    // B(b1=b1, b2=b2, general1=general1, counter=11)
    //...
}
fun main(args: Array<String>) {
    val a = A("a1", "general1")
    doSomething(a)
    val b = B("b1", "b2", "general1")
    doSomething(b)
}
You still need to duplicate the copy() method into each sub-class.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论