You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala子类实例访问父类字段报错,正确实现方式是什么?

问题分析与解决方案

嘿,我来帮你解决这个Scala子类访问父类字段的问题~

为什么会出现编译错误?

你遇到的错误super may not be used on variable age,核心原因是:

  • Scala中var类型的成员不能通过super关键字访问。var是可变变量,子类继承父类的var后,拿到的是同一个变量的引用——你在Cat类里写age=4,本质是直接修改了从Animal继承来的那个age变量的值,而不是定义了一个子类自己的age字段。此时父类的age和子类的age是同一个东西,不存在“父类的age值”(已经被改成4了)。
  • super关键字的设计目的是访问被子类重写的val或def成员,对于var这种只能被赋值、不能被override的成员,Scala不允许用super来访问。

正确的实现方式

根据你的需求,分两种场景给出解决方案:

场景1:想同时保留父类和子类的字段值

如果你希望子类有自己的age值,同时能访问父类的初始age值,需要把父类的age改成val,然后子类通过override重写它,这样就能用super访问父类的val了:

object MyClass {
 def main(args: Array[String]) {
 val dog=new Dog("s")
 dog.sayHello
 println(dog)
 val cat =new Cat("nancy")
 cat.sayHello
 println(cat)
 cat.superPrnt // 现在会输出父类的age=5
 }
 abstract class Animal() {
 val greeting:String="boo"
 val age:Int=5 // 把var改成val
 def sayHello{println(greeting)}
 override def toString=s"I say $greeting and i am $age years old"
 }
 class Dog(name:String) extends Animal {
 override val greeting="woof"
 override val age=2 // override父类的val
 }
 class Cat(name:String) extends Animal{
 override val greeting="meow"
 override val age=4 // override父类的val
 def superPrnt{println(super.age)} // 可以正常访问父类的age了
 }
}

运行这段代码,cat.superPrnt会输出5,而cat.age的值是4,两者互不干扰。

场景2:只是想修改继承的var值,需要保存父类初始值

如果你不想把父类的age改成val,只是想获取父类的初始值(比如5),可以在子类构造时先保存这个值,再修改age:

object MyClass {
 def main(args: Array[String]) {
 val dog=new Dog("s")
 dog.sayHello
 println(dog)
 val cat =new Cat("nancy")
 cat.sayHello
 println(cat)
 cat.superPrnt // 输出父类初始值5
 }
 abstract class Animal() {
 val greeting:String="boo"
 var age:Int=5
 def sayHello{println(greeting)}
 override def toString=s"I say $greeting and i am $age years old"
 }
 class Dog(name:String) extends Animal {
 override val greeting="woof"
 age=2
 }
 class Cat(name:String) extends Animal{
 override val greeting="meow"
 val parentAge = age // 在修改前保存父类的初始age值
 age = 4
 def superPrnt{println(parentAge)} // 输出保存的父类初始值
 }
}

这样cat.superPrnt会输出5,而cat.age是修改后的4。

补充说明

你的Dog类里age=2的写法是正确的,它直接修改了从Animal继承来的var变量,所以dog.age的值是2,父类的初始值5已经被覆盖了。

内容的提问来源于stack exchange,提问作者Gaurav Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:36:00