在Scala中对子函数参数进行子类型化

时间:2012-06-14 19:50:56

标签: scala polymorphism

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

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在那里。

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

提前致谢。

2 个答案:

答案 0 :(得分:3)

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

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

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


使用

Ordering可能有点笨拙,但Ordered有一些含义可以让你编写这样的代码:

import math.Ordered._

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

所以你甚至不会妥协方便。 (顺便说一下,Ordered相当于Java的Comparable

答案 1 :(得分:2)

在这种情况下,使用math.Orderedmath.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
}

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