默认封闭
仓颉虽然支持了完整的面向对象范式,支持了类继承的特性,但仓颉并不鼓励滥用继承,尤其是默认可继承可覆盖。默认可继承语义会使得开发者设计的库无意间被使用者增加了抽象层次,提升了不必要的复杂性,从而引起一系列工程维护问题。
出于工程友好性的考虑,仓颉采取了默认封闭的设计选择,即类默认不可被继承,方法默认也不可被覆盖(override)。开发者需要主动考虑是否需要自己的类型提供子类的能力,通过这样的约束减少了滥用继承的现象。
类默认不可继承
在仓颉中,开发者定义 class 时默认是不可继承的。如果希望该 class 有子类,必须显式使用 open
、abstract
、sealed
其中一个修饰(这些修饰符的语义有细微差别,但都允许 class 被继承)。
class A {}
class B <: A {} // error,A 不允许被继承
open class C {}
class D <: C {} // ok
成员方法默认不可覆盖
在仓颉中,开发者定义成员方法默认是不可覆盖(override)的。这意味着即使该类拥有子类,子类也无法修改该成员方法。如果希望一个成员方法可以被覆盖,必须显式使用 open
修饰。
open class A {
func f() {}
open func g() {}
}
class B <: A {
override func f() {} // error,f 不允许被覆盖
override func g() {} // ok
}