假设我有以下抽象类:
abstract class A (var is_happy : Boolean) {
def toggle_happiness();
}
Run Code Online (Sandbox Code Playgroud)
现在我想定义一个实现该toggle_happiness()方法的具体类:
class B (is_happy : Boolean) extends A (is_happy) {
def toggle_happiness() = {
is_happy = !is_happy
}
}
Run Code Online (Sandbox Code Playgroud)
Scala的编译器给了我:
error: reassignment to val
is_happy = !is_happy
^
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?我认为在我的类中is_happy引用了var由我的构造函数设置的.我和这个名字有冲突is_happy吗?
谢谢,丹
考虑Scala中的以下基类和派生类:
abstract class Base( val x : String )
final class Derived( x : String ) extends Base( "Base's " + x )
{
override def toString = x
}
Run Code Online (Sandbox Code Playgroud)
这里,Derived类参数的标识符'x'覆盖Base类的字段,因此调用toString如下:
println( new Derived( "string" ).toString )
Run Code Online (Sandbox Code Playgroud)
返回Derived值并给出结果"string".
因此,对'x'参数的引用会提示编译器自动在Derived上生成一个字段,该字段在调用toString时提供.这通常非常方便,但会导致字段的复制(我现在将字段存储在Base和Derived上),这可能是不合需要的.为了避免这种复制,我可以将Derived类参数从'x'重命名为其他内容,例如'_x':
abstract class Base( val x : String )
final class Derived( _x : String ) extends Base( "Base's " + _x )
{
override def toString = x
}
Run Code Online (Sandbox Code Playgroud)
现在调用toString返回"Base的字符串",这就是我想要的.不幸的是,代码现在看起来有些难看,使用命名参数来初始化类也变得不那么优雅了:
new Derived( _x = "string" )
Run Code Online (Sandbox Code Playgroud)
还存在忘记给派生类的初始化参数赋予不同名称并且无意中引用错误字段的风险(因为Base类实际上可能保持不同的值,所以不合需要).
有没有更好的办法?
编辑1:为了澄清,我真的只想要Base值; 导出的只是初始化基类字段所必需的.该示例仅引用它们来说明随后出现的问题. …