scala中的子类化和类型化

scala中的子类化和类型化,scala,types,Scala,Types,我在Scala中正确键入时遇到了问题——我想做类似的事情,在类层次结构上施加顺序,但是子类允许compare方法只处理它们自己类型的参数 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 } 下面的方法是有效的,但我被迫

我在Scala中正确键入时遇到了问题——我想做类似的事情,在类层次结构上施加顺序,但是子类允许compare方法只处理它们自己类型的参数

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
}
下面的方法是有效的,但我被迫永远对父类及其子类施加类型特异性。这就成了一场需要正确推理的噩梦

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
}

abstract class Parent[T我同意这个问题有点烦人,但是如果你正在寻找的行为被允许,那就有点奇怪了

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
基本上,使用继承来强制这样的属性会有点奇怪……理论上它可能会起作用,但这与继承的目的不同。相反,您可以在需要时在方法中指定
有序的
约束:

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

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

谢谢,这是一个非常好的洞察——以前从未想过。我只是在这是一个解决方案,但坦率地说,它似乎有点臭,让我有点紧张。评论

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
}
为什么不

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

正如其他人所指出的,根据您的比较标准,
父类
序列不会排序,因为它的子类是不可比较的。只有它的子类是
排序的
,所以在那里实现这个特性。

Luigi,我认为这是正确的答案。我认为我是从Java OO范式来处理这个问题的,通常需要订购一组不知道其基本类型的家长。至少在我的小环境中,我开始意识到,如果我正确设置了功能方法,我将知道集合的类型。

如果我们有
这种类型
,您可能已经能够编写
抽象c类父对象{this:Ordered[ThisType]=>/**/}
。如果对象为(非泛型)类
A
允许与类
A
的其他对象进行比较,然后,根据定义,
A
的所有子类的对象都允许与类
A
的对象进行比较,而不仅仅是与它们自己的类型进行比较。您不需要子类。子类拥有父类拥有的所有功能和更多功能。(这是“利斯科夫替代原则”正在发挥作用。)任何依赖于反向执行的设计都可能充满问题——理论上肯定不可靠。这是可行的,尽管您失去了在编译时检查其安全性的能力。在我看来,这是一个很大的损失。不过,就代码的结构而言,这对于函数式编程来说并不是非典型的;无论它是否好或者不是,我不确定。只是你失去了类型安全性,这不太好。
abstract class Parent
class A extends Parent with Ordered[A] {...}
class B extends Parent with Ordered[B] {...}