scala:性状的抽象比较法

tnkciper  于 2021-07-14  发布在  Java
关注(0)|答案(2)|浏览(418)

我有一个特点,就是我想在子类中实现一个大小比较函数:

trait A {
    def isLessThan(that: A): Boolean
    ...
}
class SubOfA() extends A {
    ...
    override def isLessThan(that: SubOfA): Boolean = {
        this.size < that.size
    }
    ...
}

但是,该方法不是有效的重写,因为参数类型为 SubOfA 而不是 A .
我也试过让论点类型 this.type ,但是当我从抽象设置调用方法时,我不能使用类型为的对象 A 作为论点:

...
(foo: A, bar: A) => foo.isLessThan(bar)

这应该是类型 foo.type 而不是 A 它们是一样的,但我认为编译器还不知道。
有没有办法让这样的事情发生?我找遍了所有地方想找到答案,但什么也找不到。也许我不知道该问什么问题。

nmpmafwu

nmpmafwu1#

可以使用以下方法修复第一种方法:

class SubOfA() extends A {

    override def isLessThan(that: A): Boolean = that match {
        case that : subOfA =>  this.size < that.size
        case _ => throw new UnsupportedOperationException("Wrong comparison") //or whatever behaviour deemed suitabe here
    }

}
bgtovc5b

bgtovc5b2#

你可以用 F-Bounded 多态性(java上的解决方案是什么),或者 Typeclasses 多态性(这将是haskell的解决方案)。
我个人的偏好是使用typeclass,因为它更具可扩展性、可维护性和类型安全性——下面是robnorris所作的更客观的比较。

f-有界。

trait Comparable[A <: Comparable[A]] { this: A =>
  def isLessThan(that: A): Boolean
}

class SubOfComparable extends Comparable[SubOfComparable] {
  val size: Int = ???
  override final def isLessThan(that: SubOfComparable): Boolean =
    this.size < that.size
}

类型类。

trait Comparator[T] {
  def isLessThan(a: T, b: T): Boolean
}

object syntax {
  object comparator {
    implicit final class ComparatorOps[T](val self: T) extends AnyVal {
      final def < (that: T)(implicit C: Comparator[T]): Boolean =
        C.isLessThan(self, that)
    }
  }
}

class Sub {
  final val size: Int = ???
}

object Sub {
  implicit val SubComparator: Comparator[Sub] = new Comparator[Sub] {
    override final def isLessThan(a: Sub, b: Sub): Boolean =
      a.size < b.size
  }
}

import syntax.comparator._
val a = new Sub(...)
val b = new Sub(...)
a < b

相关问题