教修图的网站,免费云服务器试用7天,wordpress邮件重置密码错误,建立公司参考链接#xff1a; Java中将final与继承一起使用
在之前的笔记Java静态属性和方法的继承问题中#xff0c;通过具体的实验证明#xff0c;在子类中重写父类的字段时并没有覆盖父类的字段#xff0c;只是隐藏了父类的字段。而在scala中则不同#xff0c;scala子类的同名…参考链接 Java中将final与继承一起使用
在之前的笔记Java静态属性和方法的继承问题中通过具体的实验证明在子类中重写父类的字段时并没有覆盖父类的字段只是隐藏了父类的字段。而在scala中则不同scala子类的同名字段会重写且覆盖父类的同名字段这里做了个简单实验并记录下来。
Parent.scala
class Parent { val normalStr: String Normal member of parent. def normalMethod() { println(Normal method of parent.) }
}
定义了一个字段normalStr和一个方法normalMethod()在Scala中类的字段是由一个私有属性和对应的getter/setter方法组成的。
Child.scala
class Child extends Parent { override val normalStr: String Normal member of child. override def normalMethod() { println(Normal method of child.) }
}
子类Child继承了父类Parent并override父类的normalStr和normalMethod()。
TestMain和Result
object TestMain{ def main(args: Array[String]) { val child: Child new Child println(child.normalStr) child.normalMethod() //val child1:Parent child.asInstanceOf[Parent] //采用Parent类型的变量指向创建的Child对象 val child1:Parent new Child println(child1.normalStr) child1.normalMethod() }
}
输出的结果如下
Normal member of child.
Normal method of child.
Normal member of child.
Normal method of child.
从结果可以看出子类重写并覆盖了父类的同名属性和方法
Scala子类的构造顺序
这里顺便记录下Scala子类的构造顺序这里直接用书上给出的例子以便后续查看
先写两个类一个父类Creature.scala一个子类Ant.scala:
Creature
class Creature { val range: Int 10 val env: Array[Int] new Array[Int](range) def show(): Unit { println(range) }
}
Ant
class Ant extends Creature { override val range 2
}
现在创建一个Ant的对象ant那么ant.env.length的值是多少凭第一感觉应该是10或者2然而答案是0接下来我写下ant创建的过程中构造器的运行顺序
首先调用父类Creature的构造器父类的构造器先于子类的构造器被调用所以首先把range设置为10。为了后续的说明这里说明下类的字段是由一个私有属性和对应的getter和setter方法组成的而子类在重写父类的同名字段时对于val类型的属性子类重写了getter方法。接下来初始化env数组所以需要调用range的getter方法然而子类已经重写了getter方法且子类并没初始化所有的字段都是对象创建过程中内存清零后的默认值所以此时range的值为0。这也就解释了上述问题的疑问。接下来调用子类的构造器range被设为2。
所以在构造器中对象的初始化不应该依赖于val的值因为val的值对应的getter方法可能会被子类重写覆盖。解决办法有
将val声明为final。简单高效但是不够灵活在超类中将val声明为lazy。简单灵活但是不够高效还有种就是子类中使用提前定义语法。这个就不介绍了
ant对象调用show()方法输出的则是子类range的值即为2。而在Java中则是父类的range的值10。主要原因还是由于在Scala中子类重写父类的属性或者方法覆盖了父类的属性和方法而在Java中只有非静态的方法会被子类重写覆盖而非静态/静态属性和静态方法都只是被隐藏了。
主要参考《快学Scala》