.. _classes: ===== 类 ===== 在 Daslang 中,类是旨在提供 OOP 功能的结构的扩展。 类提供单父继承、抽象和虚拟方法、初始值设定项和终结器。 基本的类声明类似于结构体的声明,但使用``class``关键字:: class Foo { x, y : int = 0 def Foo { // 自定义初始化器 Foo`set(self,1,1) } def set(X,Y:int) { // 内联方法 x = X y = Y } } 初始值设定项是名称与类的名称匹配的函数。 类可以有多个具有不同参数的初始化器:: class Foo { ... def Foo(T:int) { // 自定义初始化器 self->set(T,T) } def Foo(X,Y:int) { // 自定义初始化器 Foo`set(self,X,Y) } } .. _classes_finalizer: 终结器可以显式定义为名为 ``finalize`` 的 void 函数:: class Foo { ... def finalize { // 自定义终结器 delFoo ++ } } 替代语法为:: class Foo { ... def operator delete { // 自定义终结器 delFoo ++ } } 不能保证隐式调用终结器 (参阅 :ref:`Finalizers `). 派生类需要使用 ``override`` 关键字显式地覆盖方法:: class Foo3D : Foo { z : int = 13 def Foo3D { // 覆盖默认初始值设定项 Foo`Foo(self) // 显式调用父类初始值设定项 z = 3 } def override set(X,Y:int) { // 覆盖方法变量 Foo`set(self,X,Y) // 直接调用生成的方法函数 z = 0 } } 类可以使用 ``abstract``' 关键字定义抽象方法:: class FooAbstract { def abstract set(X,Y:int) : void // 内联方法 } 抽象函数需要是完全限定的,包括它们的返回类型。 类成员函数的推断方式与常规函数相同。 Sealed 函数不能被覆盖。``sealed``关键字用于防止覆盖:: class Foo3D : Foo { def sealed set(X,Y:int ) { // Foo3D 的子类不能再覆盖此方法 xyz = X + Y } } 不能从密封类继承。``sealed`` 关键字用于防止继承:: class sealed Foo3D : Foo // Foo3D 不能再继承自 ... 名为 ``self`` 的指针在任何类方法中都可用。 可以通过 ``new`` 运算符创建类:: var f = new Foo() 局部类变量不安全:: unsafe { var f = Foo() // 不安全 } 可以使用 ``->`` 语法调用类方法:: f->set(1,2) 或者,使用 .运算符(在大多数情况下,除了一些宏):: f.set(1,2) 也可以显式调用该方法的特定版本:: Foo`set(*f,1,2) 类方法可以是常量:: class Foo { dir : float3 def const length { return length(dir) // dir 在这里是 const float3 } } 类方法可以是运算符:: class Foo { dir : float3 def Foo ( x,y,z:float ) { dir = float3(x,y,z) } def Foo ( d:float3 ) { dir = d } def const operator . length { return length(dir) } def operator . length := ( value:float ) { dir = normalize(dir) * value } def const operator + ( other:Foo ) { return Foo(dir + other.dir) } } 类字段可以声明为 static,即在类的所有实例之间共享:: class Foo { static count : int = 0 def Foo { count ++ } def finalize { count -- } } 类方法可以声明为 static。静态方法无权访问 `self`,但可以访问静态字段:: class Foo { static count : int = 0 def static getCount : int { return count } } let count = Foo`getCount() // 他们可以在类外访问 ---------------------- 实现细节 ---------------------- 类初始化器是通过使用 `construct` 语法添加本地 ``self`` 变量生成的。 该方法的主体以 ``with self`` 表达式为前缀。 最后一个表达式是 ``return <- self``:: def Foo ( X:int const; Y:int const ) : Foo { var self:Foo <- Foo(uninitialized) with ( self ) { Foo`Foo(self,X,Y) } return <- self } 类方法和终结器是通过提供额外的参数 ``self`` 生成的。 该方法的主体以 ``with self`` 表达式为前缀:: def Foo3D`set ( var self:Foo3D; X:int const; Y:int const ) { with ( self ) { Foo`set(self,X,Y) z = 0 } } 调用虚拟方法是通过 invoke 实现的:: invoke(f3d.set,cast f3d,1,2) 每个基类都有一个 ``__rtti`` 指针和一个 ``__finalize`` 函数指针。 此外,还会为每个成员函数添加一个函数指针:: class Foo { __rtti : void? = typeinfo(rtti_classinfo type) __finalize : function<(self:Foo):void> = @@_::Foo'__finalize x : int = 0 y : int = 0 set : function<(self:Foo;X:int const;Y:int const):void> = @@_::Foo`set } ``__rtti``包含特定类实例的 rtti::TypeInfo。 rtti 模块中有辅助函数可以安全地访问 class_info:: def class_info ( cl ) : StructInfo const? 当为类指针调用 finalizer 时,将调用 ``finalize`` 指针。 这样,在基类指针上调用 delete 时,将调用派生终结器的正确版本。