我正在尝试在Scala中实现可堆叠的特征模式(类似于http://www.artima.com/scalazine/articles/stackable_trait_pattern.html)。这是我的尝试。我开始定义一个简单的类:
class Topping(var name:String)
该类声明应自动为名为“name”的变量创建getter和setter方法。那么我创建了一个扩展这个类的特性:
trait LoggingNameTrait extends Topping {
override def name_=(aName:String) {
print(aName)
super.name_=(aName) // this line doesn't compile
}
}
如果上面的代码有效,它应该覆盖“name”字段的隐式setter,在控制台上打印它,然后调用使用该trait的类的setter。我得到一个“超级可能不会用于变量名称”。
你知道为什么Scala编译器不允许我覆盖隐式setter吗?
答案 0 :(得分:7)
这是一项实施限制:super
仅适用于def
s。
答案 1 :(得分:2)
setter不会被称为name_
,它被称为name_=
(注意等号)。
答案 2 :(得分:1)
我相信虽然scala在某种意义上会在您声明变量时自动创建name_=
方法,但除非您明确声明,否则它不能用于覆盖等。但是,以下内容应该有效:
class Topping(var _name:String) {
def name : String = _name
def name_= (s : String) { _name = s }
}
trait LoggingNameTrait extends Topping {
abstract override def name_=(aName:String) {
print(aName)
super.name_=(aName) // this line doesn't compile }
}
这应该在功能上等同于您最初尝试的内容,
val t = new Topping with LoggingNameTrait
t.name = "Name"
将打印出来"姓名"并设置内部_name
值,以便val s = t.name
分配"名称"如你所料,到s
。唯一的区别是setter和getter函数的更明确的定义。