2010-05-09 21 views
3

我在Scala中定義了一個正常的樹。在Scala中擴展現有的數據結構

sealed abstract class Tree 
object Tree { 
    case class Node (...) extends Tree 
    case class Leaf (...) extends Tree 
} 

現在我想添加一個成員變量到樹中的所有節點和樹葉。 擴展關鍵字可能嗎?或者我必須通過添加[T]來修改樹類嗎?

更新:
看來我的問題被誤解了。 示例應清除它:

我需要這個樹結構(實際上更復雜的東西)在一個上下文中有兩個雙打。 在另一種情況下,我需要它有一個字符串。然而在另一種情況下,我需要沒有任何(額外)成員的純樹。而我想第一個兩個變種爲的第三個變種。 僞代碼:

DTree extends Tree with Touple2[Double, Double] 
object DTree { 
    case class Node (...) extends Tree.Node with Touple2[Double, Double] 
    case class Leaf (...) extends Tree.Leaf with Touple2[Double, Double] 
} 

STree extends Tree with String 
object DTree { 
    case class Node (...) extends Tree.Node with String 
    case class Leaf (...) extends Tree.Leaf with String 
} 

... 

def f (t : Tree) { ... } 

我想F到能夠處理所有的樹木。

回答

0

您不必修改樹類,因爲你總是可以創建樹和節點/葉之間的中介子類:

 

abstract class ExtraMember[T](member:T) extends Tree 
 

但是,你不能在一個特點的混合實現這一目標如果您希望將額外成員作爲參數傳遞給Node和Leaf。

0

抽象類可以有構造函數(特徵可能不會),那麼你可以把公共元素在abstract class Tree

abstract 
class Tree(te1: String, te2: Int) 

case 
class Node(...) 
extends Tree(te1Arg, te2Arg) 

等。請注意,您必須在子類定義的extends子句中提供基類構造函數參數。

+0

您修改了Tree類。我想避免這種情況,因爲它在很多地方都有使用,我只需要在一個地方需要更豐富的樹。 – 2010-05-09 17:40:27

+2

@ŁukaszLew:然後在繼承結構中引入一個新層,用於捕獲這種區別,並將共享元素放置在該級別的(抽象)類之一中。 – 2010-05-09 18:09:32

0

如果您要添加的成員對所有Tree對象(和子類)有效,那麼合乎邏輯的地方就是將它們放入Tree對象本身。

你在這裏有兩種技術可用。正如其他人所提到的,你可以在抽象類使這些構造PARAMS:

sealed abstract class Tree(prop1: String, prop2: Int) 

case class Node(prop1: String, prop2: Int) extends Tree(prop1, prop2) 

你也可以讓他們定期丘壑/ VAR和專門的子類。這無疑是一個更好的解決方案,因爲它更容易,而不是計算的簡單菊花鏈式他們通過構造這些屬性:

sealed abstract class Tree { 
    def prop1 : String 
    def prop2 : Int 
} 

case class Node(a:String, b:Int) extends Tree { 
    lazy val prop1 = "[" + a + "]" 
    lazy val prop2 = b + 42 
} 

使用懶瓦爾斯在這裏更容易推理的對象的初始化順序,如果該屬性從不使用,也可以避免任何計算開銷。這也很好地顯示了Scala中的方法如何通過屬性實現,即所謂的統一訪問原則。

如果採取這種方式,那麼它也可以通過一個特點,介紹屬性:

sealed abstract class Tree 

trait TreeExtras { 
    def prop1 : String 
    def prop2 : Int 
} 

case class Node(a:String, b:Int) extends Tree with TreeExtras { 
    lazy val prop1 = "[" + a + "]" 
    lazy val prop2 = b + 42 
} 

你也應該隨時使用自助型等中的。

2

如果我正確理解你,你希望你的一些樹節點有一個類型的字段。我認爲你要找的是abstract type。它們就像泛型一樣,但更適合分類。像這樣的東西。

sealed abstract class Tree 

trait TypedTree { 
    type T 
    val value:T 
} 

然後,當我修改你的榜樣,結果:

trait DTree extends TypedTree { 
    type T = Touple2[Double, Double] 
} 
object DTree { 
    case class Node (...) extends Tree.Node with DTree 
    case class Leaf (...) extends Tree.Leaf with DTree 
} 

trait STree extends TypedTree { 
    type T = String 
} 
object DTree { 
    case class Node (...) extends Tree.Node with STree 
    case class Leaf (...) extends Tree.Leaf with STree 
} 

這增加了間接的級別。但是我覺得你在一個步驟中需要兩個概念化概念。