Skip to main content
 首页 » 编程设计

scala之从函数式迁移到 OO 的问题

2025年05月04日109arxive

我习惯于使用函数式编程(主要是 Haskell),我从 OO(scala)开始。

我在翻译我的代码时遇到了麻烦。例如,这是我对 B-tree 的 Haskell 定义:

data BTree a =  
    Leaf 
    |Node2 (BTree a) a (BTree a) 
    |Node3 (BTree a) a (BTree a) a (BTree a) 
    deriving (Eq,Read,Show)  

这很简单。我的树是空的,或者它有一个值并且是两棵树的父亲,或者它是三棵子树的父亲。

OO上有什么?我没有任何线索。我只是无法弄清楚我该如何以理智的方式做到这一点。

请您参考如下方法:

这里有一些很好的答案,但我认为他们都错过了展示你所缺少的观点的机会。所以,你已经证明了这一点:

data BTree a =  
    Leaf 
    |Node2 (BTree a) a (BTree a) 
    |Node3 (BTree a) a (BTree a) a (BTree a) 
    deriving (Eq,Read,Show) 

并询问您如何以面向对象的方式实现这一点。所以,这里是:

最重要的事情
trait Tree[A] { 
  // not required because it is inherited from AnyRef 
  // def equals(other: Any): Boolean 
 
  // not required because it is inherited from AnyRef 
  // def toString: String 
 
  // does not belong in the object 
  // def fromString(input: String): Tree[A] 
 
  // Stuff that is missing but is needed 
  def isEmpty: Boolean 
  def value: Option[A] 
  def subtrees: Seq[Tree[A]] 
  def iterator: Iterator[A] 
  def depthFirstIterator: Iterator[A] 
  def breadthFirstIterator: Iterator[A] 
} 

所以,问题是这样的:当你谈到面向对象时,你有一个 BTree、一个手指树或任何其他不相关的树结构。事实上,它应该被隐藏起来。相关的是你可以用它做什么。

您在这样做时遇到了麻烦,因为您正在从不应该的方向准确地解决问题。

不那么重要的事情
sealed abstract class BTree[A] extends Tree[A] 
object BTree { 
  def apply[A](input: String): BTree[A] = { /* factory */ null.asInstanceOf[BTree[A]] } 
  private case object Leaf extends BTree[Nothing] { 
    // method implementation 
  } 
  private case class Node2[A](value: A, private one: BTree[A], private two: BTree[A]) extends BTree[A] { 
    // method implementation 
  } 
  private case class Node3[A](value: A, private one: BTree[A], private two: BTree[A], private three: BTree[A]) extends BTree[A] { 
    // method implementation 
  } 
} 

现在在这里你实际上提供了一个实现,但是 BTree 的细节是完全隐藏的。您只能使用 Tree 的方法。已定义。

这是理想的面向对象架构:客户端依赖于接口(interface),数据结构是隐藏的。