在Scala中实现抽象类

阿马钦

我开始学习Scala编程和OOP编程。我不理解抽象类的概念。我读过这个例子:

考虑为带有两个运算(包括和)的整数集编写类的任务。(s incl x)应该返回一个新集合,其中包含元素x和集合s的所有元素。(s包含x)如果set s包含元素x,则应返回true,否则应返回false。这样的集合的接口由下式给出:

abstract class IntSet {
  def incl(x: Int): IntSet
  def contains(x: Int): Boolean
}

假设我们计划将集合实现为二叉树。有两种可能的树木形式。空集的树,以及由整数和两个子树组成的树。这是它们的实现。

class EmptySet extends IntSet {
  def contains(x: Int): Boolean = false
  def incl(x: Int): IntSet = new NonEmptySet(x, new EmptySet, new EmptySet)
}



class NonEmptySet(elem: Int, left: IntSet, right: IntSet) extends IntSet { 
  def contains(x: Int): Boolean =
    if (x < elem) left contains x
    else if (x > elem) right contains x else true
  def incl(x: Int): IntSet =
    if (x < elem) new NonEmptySet(elem, left incl x, right)
    else if (x > elem) new NonEmptySet(elem, left, right incl x) 
    else this
}

EmptySet和NonEmptySet都扩展了IntSet类。这意味着类型EmptySet和NonEmptySet符合类型IntSet –在需要IntSet类型的值的任何地方都可以使用类型EmptySet或NonEmptySet的值。

我不清楚为什么引入匿名类很有用,因为在扩展匿名类的两个类中,又包含了incl和contains的定义。

谢谢!

巴勃罗·弗朗西斯科·佩雷斯·伊达尔戈

使用InClass(这是一个抽象类,而不是一个匿名类)的主要优点是它定义了一种元素类型,其实例必须始终实现inclcontains因此允许您在管理设置对象的情况下抽象实现细节。

一个很好的例子是,您可以拥有一组集合EmptyNomEmpty一起使用抽象类给出的协定来模糊地使用它们:

val l = List[IntSet](new EmptySet, new NomEmptySet(1, new EmptySet, new EmptySet)
val setsContainingThree = l.filter(_.contains(3))

您的代码利用了这一点,请注意,我写了,new NomEmptySet(1, new EmptySet, new EmptySet)但也可能是:

new NomEmptySet(1, new EmptySet, new NomEmptySet(2, new EmptySet, new EmptySet))

你的NonEmptySet构造函数需要InSet因此您的实际参数可以通过任何类型的为子类InSet,即:EmptySetNonEmptySet

这不是Scala或Java功能,而是OOP的基本原理。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章