2012-06-14 138 views
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在那里。

有没有一种方法可以指定方法签名中类的类型?

在此先感谢。

回答

3

我强烈建议你看看Ordering类型的类。

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

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


Ordering可以是一个有点笨拙的使用,但Ordered具有implicits,让你写这样的代码:

import math.Ordered._ 

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

所以你甚至不妥协的便利。 (顺便说一下,Ordered等同于Java的Comparable

+0

非常感谢。有序似乎正是我所需要的。作为奖励,我还发现PartiallyOrdered,我需要在我的代码中的其他地方。 – lasaro

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 
} 

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

+0

太好了。尽管Ordered似乎解决了手头的问题,但我发现F界有限的多态可能真的有用。 – lasaro