【发布时间】:2012-01-23 21:56:21
【问题描述】:
我正在阅读示例书中的 Scala,其中几乎每个示例都有以下结构:
abstract class Stack[A] {
def push(x: A): Stack[A] = new NonEmptyStack[A](x, this)
def isEmpty: Boolean
def top: A
def pop: Stack[A]
}
class EmptyStack[A] extends Stack[A] {
def isEmpty = true
def top = error("EmptyStack.top")
def pop = error("EmptyStack.pop")
}
class NonEmptyStack[A](elem: A, rest: Stack[A]) extends Stack[A] {
def isEmpty = false
def top = elem
def pop = rest
}
我有以下两个相互关联的问题: 1) 将空元素和非空元素表示为单独的类是否是一种常见的 Scala 实践?如果是,那为什么? 2) 为什么孩子们在可能的情况下都实现相同的愚蠢方法“isEmpty”,而且对我来说,在父类中这样做更明智?
我想了解这里所涉及的最深刻的哲学。
【问题讨论】:
-
谢谢,看来这个部门可以追溯到函数式或更准确地说是“面向列表”编程的基石之一,我很久以前在简要接触 Erlang、Clojure 和口齿不清。所以这一定有一个非常重要的意义。至于第二个问题,感谢您的回答,我明白这只是一个太简单的例子,无法见证这种方法的全部力量。
-
这是常见的做法吗?集合 - 也许,一般应用程序编码,我改为使用 Option。对我来说,你的两个问题都有一个答案——作者的目的是演示如何使用继承,特别是抽象类和方法。 isEmpty、top、pop被演示为抽象方法,因此必须通过继承类来实现,并且可以有不同的实现。这只是一个意见,所以不张贴作为答案。希望对您有所帮助!
-
此外,这个除法可以帮助您回答如下问题:“如果我将一个空堆栈传递给它,如何编写一个在堆栈上运行但在 编译时失败的函数"
-
在父级和子级中实现
isEmpty(或类似方法)之间存在权衡。将实现推迟到子类的一个好处是,如果您希望添加新的子类,则不必修改父类的代码。
标签: class scala inheritance methods