Scala中如何递归调用父类方法并遍历完整类层级?
Scala递归调用父类方法未遍历类层级的优化方案
问题重现
你遇到的核心问题是:仅父类B重写了f方法时,子类C、D未重写f的情况下,调用d.f不会自动遍历所有子类的g值参与计算。原代码及问题表现如下:
class A { def f: Int = 1 def g: Int = 0 } class B extends A { override def f: Int = g + super.f override def g: Int = 10 } class C extends B{ override def g: Int = 20 } class D extends C{ override def g: Int = 30 } val d = new D printf("f.d = " + d.f) // 实际输出31,预期61
问题根源很明确:调用d.f时,实际执行的是B中重写的f方法,其中g会动态绑定到D的g(30),但super.f会直接跳转到A的f(1),中间C、B自身的g值并未被纳入计算,因此结果为30+1=31,而非预期的30+20+10+1=61。
优化方案:利用Scala特质线性化实现链式累加
不需要每个子类都重复重写f,可以借助Scala的特质线性化特性,实现自动遍历类层级的累加逻辑:
// 定义特质,封装f的累加逻辑 trait AddsG { def f: Int def g: Int override def f: Int = g + super.f } class A { def f: Int = 1 def g: Int = 0 } // 每个子类只需混入AddsG特质,专注重写g即可 class B extends A with AddsG { override def g: Int = 10 } class C extends B with AddsG { override def g: Int = 20 } class D extends C with AddsG { override def g: Int = 30 } val d = new D println(s"d.f = ${d.f}") // 输出61,符合预期
方案原理
Scala的类继承和特质混入会生成一个线性化顺序,对于D实例来说,顺序为:D → AddsG → C → AddsG → B → AddsG → A。
当调用d.f时,会依次触发每个AddsG中的f实现:
- D对应的AddsG:执行
30 + super.f,这里的super.f指向C的AddsG中的f - C对应的AddsG:执行
20 + super.f,这里的super.f指向B的AddsG中的f - B对应的AddsG:执行
10 + super.f,这里的super.f指向A的f - A的f返回基础值1
最终累加结果为30+20+10+1=61,既实现了遍历整个类层级的需求,又避免了子类重复编写f的冗余逻辑。
内容的提问来源于stack exchange,提问作者bbrn
相关产品推荐
相关产品推荐

