2015-03-31 116 views
1

我開始學習Scala編程和OOP編程。 我不明白抽象類的概念。我讀過這個例子:在Scala中實現抽象類

考慮用兩個操作,incl和contains編寫一組整數的類的任務。 (s包括x)應該返回一個新的集合,其中包含元素x以及集合s的所有元素。 (s包含x)應該返回true,如果集合s包含元素x,否則應該返回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的定義。

謝謝!

+0

我無法理解遞歸如何在incl方法中工作。請幫忙 – 2017-04-02 09:26:25

回答

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,即:EmptySetNonEmptySet

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

0

該類不是匿名的,它只是抽象的。其中 - 簡單的話 - 意味着你不能實例化它。但是,您可以在方法簽名中使用它...您永遠不會知道哪個實現傳遞給了您的方法,但都提供了與它們交互的相同接口(因爲兩者都是IntSet s)。

如果有幫助,您可以將抽象類作爲與方法實現的接口或作爲特徵的簡單形式來考慮。