在抽象类中,我如何指定方法的返回值与它所属的具体类具有相同的类型?
例如:
abstract class Genotype {
def makeRandom(): Genotype // must return subclass type
def mutate(): Genotype // must return subclass type
}
我想说,无论何时在具体的基因型类上调用mutate()
,您都要确保返回同一基因型类的另一个实例。
我不希望以Genotype[SpecificGenotype259]
的方式使用类型参数,因为该类型参数可能会在整个代码中激增(同样,它是多余的和令人困惑的)。我倾向于通过扩展各种特征来定义具体的基因型类。
答案 0 :(得分:5)
abstract class Genotype[T <: Genotype[T]] {
def makeRandom(): T
def mutate(): T
}
class ConcreteGenotype extends Genotype[ConcreteGenotype] {
def makeRandom(): ConcreteGenotype = ???
def mutate(): ConcreteGenotype = ???
}
答案 1 :(得分:3)
abstract class Genotype {
type T <: Genotype
def makeRandom(): T
def mutate(): T
}
这是你想要的吗?
答案 2 :(得分:1)
我建议针对这种情况使用参数化模块:
trait GenotypeSystem {
type Genotype <: GenotypeLike
trait GenotypeLike {
def makeRandom(): Genotype
def mutate(): Genotype
}
}
// Example implementation
object IntGenotypeSystem extends GenotypeSystem {
case class Genotype(x: Int) extends GenotypeLike {
def makeRandom() = copy(x = Random.nextInt(10))
def mutate(): Genotype = copy(x = x + Random.nextInt(3) - 1)
}
}
// Example abstract usage
def replicate(gs: GenotypeSystem)(g: gs.Genotype, n: Int): Seq[gs.Genotype] =
Seq.fill(n)(g.mutate())
这种方法很容易适应未来的修改和扩展,例如向GenotypeSystem
添加其他类型。
答案 3 :(得分:0)
使用协变返回类型可能适用于您的情况吗?
abstract class Genotype {
def makeRandom(): Genotype // must return subclass type
def mutate(): Genotype // must return subclass type
}
class ConcreteGenotype(val a : Int) extends Genotype {
override def makeRandom(): ConcreteGenotype = new ConcreteGenotype(a + 1)
override def mutate(): ConcreteGenotype = new ConcreteGenotype(a + 2)
}
def useAbstractGenotype(g : Genotype) = g.mutate
val cg = new ConcreteGenotype(0) // cg: ConcreteGenotype = ConcreteGenotype@6c1c19c6
cg.mutate // res2: ConcreteGenotype = ConcreteGenotype@3fc1058a
useAbstractGenotype(cg) // res3: Genotype = ConcreteGenotype@13515ded