1

我正在尝试定义一个抽象类,该类具有运算符来比较该类的两个实例。然而,在具体化类时,我希望这些方法只比较相同类型的实例。像这样的东西

abstract class ComparableSuper{
  def <(other: ComparableSuper): Boolean  
  def <=(other: ComparableSuper): Boolean  
  def >(other: ComparableSuper): Boolean
  def >=(other: ComparableSuper): Boolean
}


class Comparable (val a: Int) extends ComparableSuper {
   def <(other: Comparable): Boolean = this.a < other.a
   def >(other: Comparable): Boolean = this.a > other.a
   def <=(other: Comparable): Boolean = this.a <= other.a
   def >=(other: Comparable): Boolean = this.a >= other.a
}

当然,这段代码不会编译,因为我没有覆盖抽象类中的方法。但是,如果我在方法中将 Comparable 更改为 ComparableSuper,我将无法保证字段 a 存在。

有没有办法可以在方法签名中指定类的类型?

提前致谢。

4

2 回答 2

3

我强烈建议您查看Ordering类型类。

我发现,这个问题的类型类方法比做它的方法要好得多Comaprable(你想要比较的对象实际上是 extend Comparable)。

使用类型类方法,您还将为您提供更多的类型安全性和灵活性。您实际上可以Ordering为现有类(您无法控制和更改的类)定义实例。


Ordering使用起来可能有点笨拙,但Ordered有一些隐式可以让你编写如下代码:

import math.Ordered._

def isGreater[T : Ordering](a: T, b: T) = a > b

因此,您甚至不会损害便利性。(顺便说一下,Ordered相当于Java的Comparable

于 2012-06-14T20:10:40.090 回答
2

在这种情况下使用math.Orderedormath.Ordering是一个更好的主意,但如果您确实需要这种模式,您可以使用F -bounded polymorphism

trait Foo[A <: Foo[A]] {
  def f(that: A): Int
}

class Bar(val x: Int) extends Foo[Bar] {
  def f(that: Bar) = this.x - that.x
}

参数化超类型涉及一些语法开销,但它允许您拥有需要相同子类实例的方法。

于 2012-06-14T22:03:55.697 回答