在Scala中实现抽象类

时间:2015-03-31 08:14:31

标签: java scala oop abstract-class

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

  

考虑使用两个操作(包含和包含)为整数组写一个类的任务。 (s incl x)应返回一个新集合,其中包含元素x以及集合s的所有元素。 (s contains x)如果set包含元素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类型 - 类型为EmptySet或NonEmptySet的值可以在需要IntSet类型的值的任何地方使用。

我不清楚为什么引入匿名类是有用的,因为在扩展匿名类的两个类中,还有include和contains的定义。

谢谢!

2 个答案:

答案 0 :(得分:0)

这个类不是匿名的,它只是抽象的。哪个 - 简单的话 - 意味着你无法实例化它。但是,您可以在方法签名中使用它...您永远不会知道哪个实现传递给您的方法,但两者都提供了与它们交互的相同接口(因为它们都是IntSet s)。 / p>

如果有帮助,您可以将抽象类视为与方法实现的接口,或者作为特征的简单形式。

答案 1 :(得分:0)

使用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的子类型的任何类型,即:EmptySet或{{1} }。

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