黑猴子的家:Scala 构造顺序和提前定义

当子类重写了父类的方法或者字段后,父类又依赖这些字段或者方法初始化,这个时候就会出现问题,比如

class Creature {
 val range: Int = 10
 val env: Array[Int] = new Array[Int](range)
//lazy val env: Array[Int] = new Array[Int](range)
}

class Ant extends Creature {
 //override val range = 2
 override val range = 2
}
-------------------------------------------------------------
val ant = new Ant
println(ant.range)
println(ant.env.length)

此时的构造顺序为

(1)Ant的构造器在调用它自己的构造之前,调用Creature的构造器

(2)Creature的构造器将它的range字段设为10

(3)Creature的构造器为了初始化env数组,调用range()取值器

(4)range该方法被重写以输出(还未初始化的)Ant类的range字段值

(5)range方法返回0,(这是对象被分配空间时所有整形字段的初始值)

(6)env被设为长度为0的数组。

(7)Ant构造器继续执行,将其range字段设为2.

那么env的大小是多少?是0,惊不惊喜,意不意外?

问题解决,4种方案

(1)子类不重写父类

(2)可以将val声明为final,这样子类不可改写。

(3)可以将超类中将val声明为lazy,这样安全但并不高效。

(4)还可以使用提前定义语法,可以在超类的构造器执行之前初始化子类的val字段

提前定义,颠覆三观的方法来了,哈哈 ~ ~
看着很像多继承,但是它不是多继承

class Ant2 extends {
 override val range = 3
} with Creature
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值