我不确定是否有更好的方法:
trait Animal {
val name: String
val weight: Int
type SubAnimal <: Animal
def updateName(n: String) = returnMe(n, this.weight)
def updateWeight(w: Int) = returnMe(this.name, w)
// Abstract protected method
protected def returnMe(n: String, w: Int): SubAnimal
}
case class Dog(name: String, weight: Int) extends Animal {
type SubAnimal = Dog
override def returnMe(n: String, w: Int): Dog = Dog("Dog: " + name, w)
}
case class Cat(name: String, weight: Int) extends Animal {
type SubAnimal = Cat
override def returnMe(n: String, w: Int): Cat = Cat("Cat: " + name, w)
}
val fido = Dog("Fido", 11)
println( fido )
val fido2 = fido.updateWeight(12)
println( fido2 )
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,我得到这个输出:
$ scala animal.scala
Dog(Fido,11)
Dog(Dog: Fido,12)
Run Code Online (Sandbox Code Playgroud)
我想后返回的实际类型有关动物的updateName或updateWeight已被调用(即不是Animal).我知道,如果我重写updateName和updateWeight直接,然后正确的类型将被退回,我没有使用抽象类型SubAnimal.
对于抽象类型的值与子类相同的特殊情况,是否有一些棘手的方法来转义抽象类型?
(这被称为"MyType"问题).
这应该工作:
trait Animal[T] {
self:T =>
val name: String
val weight: Int
def updateName(n: String): T = returnMe(n, this.weight)
def updateWeight(w: Int): T = returnMe(this.name, w)
// Abstract protected method
protected def returnMe(n: String, w: Int): T
}
case class Dog(name: String, weight: Int) extends Animal[Dog] {
override def returnMe(n: String, w: Int): Dog = Dog("Dog: " + name, w)
}
case class Cat(name: String, weight: Int) extends Animal[Cat] {
override def returnMe(n: String, w: Int): Cat = Cat("Cat: " + name, w)
}
Run Code Online (Sandbox Code Playgroud)
类似的东西case class Cat(name: String, weight: Int) extends Animal[Dog]会被编译器拒绝.代码被盗改编自http://oldfashionedsoftware.com/2009/12/10/self-help/
使用类型参数化?
trait Animal[A <: Animal[A]] {
val name: String
val weight: Int
def updateName(n: String) = returnMe(n, this.weight)
def updateWeight(w: Int) = returnMe(this.name, w)
// Abstract protected method
protected def returnMe(n: String, w: Int): A
}
case class Dog(name: String, weight: Int) extends Animal[Dog] {
override def returnMe(n: String, w: Int) = Dog("Dog: " + name, w)
}
case class Cat(name: String, weight: Int) extends Animal[Cat] {
override def returnMe(n: String, w: Int) = Cat("Cat: " + name, w)
}
Run Code Online (Sandbox Code Playgroud)
最近关于这个主题的一些讨论 ......你正在寻找的东西通常被称为"MyType",它的典型Scala/Java编码使用递归类型参数:
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
public final int compareTo(E o)
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
838 次 |
| 最近记录: |