要获得final
语义,请将您的初始状态传递给构造函数。
另一种模式是使用早期定义。请注意, BClass#strs 是最终的。
Final 意味着当你的初始化器完成时,值不能改变。
并失去可变状态。
但是,如果您喜欢或需要可变性,则伴随对象上的工厂可以在您构建对象时满足您的任何要求。
package inheritthewind
object Test extends App {
val a = new AClass(new AInit { val str = "Pooya" })
a.aMethod()
val b = new {
val str: String = "Pooya"
} with BClass
b.aMethod()
val b2 = new BClass {
val str: String = "Pooya"
}
b2.aMethod() // uh no, result is "nulls"
val c = CClass(new CPrototype { val str = "Pooya" })
c.aMethod()
// not allowed
//val nope = new CClass
}
trait AInit {
def str: String
}
final class AClass(init: AInit) {
private final val str: String = init.str
def aMethod() = Console println str
}
abstract class BClass {
val str: String
final val strs = str + "s"
def aMethod() = Console println strs
}
trait CPrototype extends AInit
final class CClass private() {
private var str: String = _
def aMethod() = Console println str
}
object CClass {
def apply(p: CPrototype): CClass = {
val res = new CClass
res.str = p.str
res
}
}
和
scala> :javap -pv inheritthewind.BClass
[snip]
private final java.lang.String strs;
flags: ACC_PRIVATE, ACC_FINAL
public abstract java.lang.String str();
flags: ACC_PUBLIC, ACC_ABSTRACT
public final java.lang.String strs();
flags: ACC_PUBLIC, ACC_FINAL