在scala中进行子类化和输入

时间:2012-06-02 14:34:30

标签: scala types

我在Scala中正确输入时遇到问题 - 我想做类似的事情,在类层次结构上强加Ordered,但是子类允许比较方法只使用自己类型的参数

abstract class Parent extends Ordered
class A extends Parent {
  override def compare(that : A) = 1
}
class B extends Parent {
  override def compare(that : B) = 1
}

以下是有效的,但是我永远被迫永远强加对Parent及其子类的类型特异性。这只是一个正确推理的噩梦。

abstract class Parent[T <: Parent[_]] extends Ordered[T]
class A extends Parent[A] {
  override def compare(that : A) = 1
}
class B extends Parent[A] {
  override def compare(that : B) = 1
}

是否有一种更简单的方法来命令Ordered [T]的子类上的类型?

4 个答案:

答案 0 :(得分:2)

为什么不

abstract class Parent
class A extends Parent with Ordered[A] {...}
class B extends Parent with Ordered[B] {...}

正如其他人所指出的那样,根据你的比较标准,Parent s序列不会被排序,因为它的子类不具有可比性。只有它的子类是Ordered,所以在那里实现特征。

答案 1 :(得分:1)

我同意这个问题有点烦人,但如果你正在寻找的行为被允许会有点奇怪。假设你做了

trait Parent {
    this: Ordered[ThisType]
}

// Does A need to be Ordered[A]?
trait A extends Parent

// Should B, C be comparable? If A is Ordered, then they
// have to be. But is this what you want?
class B extends A
class C extends A

// Now what?
class D extends B

基本上,使用继承强制这样的某些属性会有点奇怪......它可能在理论上有用,但它与继承的含义不同。相反,您可以在需要时在方法中指定Ordered约束:

def foo[T <: Ordered[T]](x: T) = ...

或者,如果您想将Ordered约束和其他可能的约束分组在一个通用名称下,您可以创建一个类型类型的特征:

trait Parent[A] {
    val order: Ordering[A]
}

def foo[T : Parent](x: T, y: T) {
    println(implicitly[Parent[T]].order.compare(x, y))
}

此解决方案的一个不幸方面是您无法指定sealed;如果有人能解决这个问题,我会感兴趣的。否则,你可以使用依赖类型的编程语言,他们在这方面做得更好。

答案 2 :(得分:1)

路易吉,我认为这是正确的答案。我认为我正在从Java OO范例中接近这一点,在这种范例中,通常需要在不知道其基础类型的情况下订购一组父母。至少在我的小环境中,我开始意识到如果我正确设置我的功能方法,我知道集合的类型。

答案 3 :(得分:0)

感谢这是一个非常好的见解 - 以前从未考虑过。我只是点亮这个作为解决方案,但坦率地说它看起来有点臭,它让我有点紧张。评论

abstract class Parent extends Ordered[Parent] {
  override def compare(that : Parent) : Int = {
    (this, that) match {
      case (x : A, y : A) =>  x.compare(y)
      case (x : B, y : B) =>  x.compare(y)
      case _ =>  throw new ClassCastException
    }
  }
}
class A extends Parent {
  def compare(that : A) = 1
}
class B extends Parent {
  def compare(that : B) = 1
}