Scala对象中访问Rockets Trait的calibre成员失败求助
解决Scala中Trait成员无法直接通过Trait名称访问的问题
这个问题我之前也碰到过,本质是Scala里trait的成员访问规则和你想的不一样:trait中定义的val是实例级成员,不属于trait本身的静态成员,所以你直接用Rockets.calibre肯定访问不到,必须通过实例或者调整结构来实现。
下面给你三个可行的解决方案,你可以根据自己的业务场景选择:
方案1:创建Rockets的匿名实例访问
因为Scala的trait不能直接实例化,我们可以用匿名类快速创建一个临时实例来访问calibre:
object Evaluator { def test() = { // 用匿名类实现Rockets trait,生成实例 val tempRockets = new Rockets {} print(tempRockets.calibre) } }
这个方案适合只需要临时访问一次、不需要复用实例的场景。
方案2:给Rockets添加伴生对象,把calibre移到伴生对象中
如果你希望不用实例就能直接访问calibre,可以把这个常量放到Rockets的伴生对象里,同时让trait里的calibre引用伴生对象的值,保证两边的一致性:
// 先定义Rockets的伴生对象,存放静态可访问的calibre object Rockets { val calibre = Calibre.Rocket } // 修改Rockets trait,引用伴生对象的calibre trait Rockets extends Ammo { override val calibre = Rockets.calibre override val metric = Metric.Pods def need(): Unit = Evaluator.getSupplyArray()(4) += difference() } // 现在Evaluator里可以直接访问了 object Evaluator { def test() = print(Rockets.calibre) }
这样伴生对象里的calibre是全局可访问的静态值,trait实例的calibre和它保持一致,两种访问方式都能生效。
方案3:创建继承Rockets的单例对象
如果你的场景只需要一个Rockets实例,直接定义一个单例object继承Rockets,然后访问这个单例的成员即可:
// 定义单例对象,继承Rockets trait object StandardRockets extends Rockets // Evaluator里直接访问单例的calibre object Evaluator { def test() = print(StandardRockets.calibre) }
这个方案适合需要复用同一个Rockets实例的场景,单例对象在程序运行期间只会初始化一次。
总结一下:Scala的trait和Java接口不同,它的默认成员都是绑定到实例的,想要直接通过trait名称访问成员,必须借助伴生对象或者单例实例来实现。
内容的提问来源于stack exchange,提问作者Simon Huenecke
相关产品推荐
相关产品推荐

