惯用的Scala方法来处理基础与派生类字段名称?
考虑
Scala中的以下基类和派生类:
abstract class Base( val x : String ) final class Derived( x : String ) extends Base( "Base's " + x ) { override def toString = x } 这里,派生类参数的标识符“x”会覆盖Base类的字段,因此可以像这样调用toString: println( new Derived( "string" ).toString ) 返回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 } 现在调用toString返回“Base的字符串”,这就是我想要的.不幸的是,代码现在看起来有点丑陋,使用命名参数来初始化类也变得不那么优雅: new Derived( _x = "string" ) 还有一个风险是忘记给派生类的初始化参数不同的名称,并且无意中引用了错误的字段(不希望的,因为Base类可能实际上具有不同的值). 有没有更好的办法? 编辑1:要澄清,我真的只想要Base值;对于初始化基类的字段,派生类似乎是必需的.这个例子只是引用他们来说明随后的问题. 编辑2:实际上,如果我使用var而不是vals,那么这个例子会更加清晰,因为这突出了在基类中稍后改变的值的问题: class Base( var x : Int ) { def increment() { x = x + 1 } } class Derived( x : Int ) extends Base( x ) { override def toString = x.toString } val derived = new Derived( 1 ) println( derived.toString ) // yields '1',as expected derived.increment() println( derived.toString ) // still '1',probably unexpected 编辑3:如果派生类最终隐藏基类字段,可能会有一种方法来抑制自动字段生成.看起来Scala编译器实际上可能是为你设计的,但这当然违背了更为一般的规则,即更接近的标识符(派生类“x”)隐藏更多远程标识符(Base类“ ‘X’).似乎一个相当不错的解决方案将是一个修饰符,如“noval”,也许就像这样: class Base( var x : Int ) { def increment() { x = x + 1 } } class Derived( noval x : Int ) extends Base( x ) { override def toString = x.toString } val derived = new Derived( 1 ) println( derived.toString ) // yields '1',as expected derived.increment() println( derived.toString ) // still '2',as expected 解决方法
避免复制字段的惯用方式是写
abstract class Base { val x: String } final class Derived(val x: String) extends Base { def toString = x } 但是,在您的版本中,您确实需要第二个字段,因为您有两个不同的值.正确地指出,给这些字段的名字相同可能会导致混乱. 既然你实际上并不需要在构造函数之外的构造函数参数,你可以使用这种方法(一个私有的构造函数和一个作为工厂的伴随模块): abstract class Base { val x: String } final class Derived private (val x: String) extends Base { def toString = x } object Derived { def apply(x: String) = new Derived("Base " + x) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 如何从bash提供mysql查询
- angular – 为什么TypeScript在实现时允许重复组件?
- shell中的数字和字符串比较
- 自动化测试时候重启机器时候可以调用的检测状态的脚本
- Angular Reactive Forms -- Model-Driven Forms响应式表单
- 解决WebService[WebMethod]方法返回一个SqlDataReader出错问
- bootstrap动态调用select下拉框的实例代码
- angularjs – Angular 2有官方的nuget包吗?
- Scala的MapLike,ListLike,SeqLike等每个与Map,List,Seq等进
- 我们可以将Any与一般类型匹配吗? [Scala 2.8]