考虑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值; 导出的只是初始化基类字段所必需的.该示例仅引用它们来说明随后出现的问题. …
考虑一下这个简单的Scala类:
class A(val d: Int)
Run Code Online (Sandbox Code Playgroud)
Scala(行为或生成的字节码)之间是否存在差异?
class B(d: Int) extends A(d)
Run Code Online (Sandbox Code Playgroud)
和
class B(override val d: Int) extends A(d)
Run Code Online (Sandbox Code Playgroud)
或者都是等价的?如果它们不同,那么它们的具体用例是什么?
如果A被定义为是不同的class A(var d: Int)?