英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论