[NAME] ALL.dao.class.definition [TITLE] 定义 [DESCRIPTION] 道语言里类由关键词class定义。 这个关键词后要跟类名,然后是可能的基类名等,最后是类体。 下面是 一个最简单的类定义: 1 class SimplestClass 2 { 3 } 这个类没有基类,也没有成员数据和方法。 要定义一个由用的类型,成员数据或成员方法必不可少。 0.1 成员数据和方法 道语言类支持以下几种数据成员: * 常量: 以const关键词声明; * 静态变量: 以static关键词声明; * 实例变量: 以var关键词声明; * 实例定变量: 以invar关键词声明; 这些数据成员的声明可以有也可以没有类型标注,还可以有也可以没有初始化值。 这些类型标注和初始 值声明跟函数的类型标注和缺省参数声明完全一样。 例如,下面的方式都可用来声明实例变量成员: 1 var 变量; 2 var 变量 = 初始值; 3 var 变量: 类型名; 4 var 变量: 类型名 = 初始值; 道类支持多种类型的成员方法,如构造方法,静态方法,实例方法 和操作符重载方法等。 操作符重载方法 必须使用关键词operator定义, 其他方法须使用关键词routine。 类成员的可访问性可由三个权限关键词声明: * public: 公共,无限制访问; * protected: 保护,仅可从本类和子类访问; * private: 私有,仅可从本类访问; 0.2 类实例 下面是一个没有构造方法的简单类: 1 class Contact 2 { 3 const description = 'This is a class for contact information' 4 var name = 'Nobody' 5 var address = 'Nowhere' 6 7 routine Show(){ io.writeln( name, 'lives at', address ) } 8 } 这种简单的类支持两种实例构造方法: * 调用其缺省构造函数以成员数据的缺省值初始化实例的成员数据: 1 obj = Contact() * 枚举类成员数据的初始值: 1 obj = Contact.{ 'Mike', '123 Main Street' } 成员数据的名称可被指定,这样成员值的枚举可不按其定义顺序: 1 obj = Contact.{ address = '123 Main Street', name = 'Mike' } 值得注意的是,仅不含基类和显式构造方法的类可以按这种方式构造实例。 0.3 类构造方法 类里方法名跟类名一样的成员方法将作构造方法处理。 当类以函数的方式被调用时,类的实例将被创建 , 该实例将调用适当的构造方法作初始化。 下面的例子同上,但增加了个构造方法: 1 class Contact 2 { 3 const description = 'This is a class for contact information' 4 var name = 'Nobody' 5 var address = 'Nowhere' 6 7 routine Contact( name : string, address = 'Unknown' ){ 8 self.name = name 9 self.address = address 10 } 11 12 routine Show(){ io.writeln( name, 'lives at', address ) } 13 } 现在调用该类的构造方法是生产该类实例的唯一方法: 1 var obj = Contact( 'Mike', '123 Main Street' ) 类的构造方法也跟普通函数和方法一样可以根据参数类型重载: 1 class Contact 2 { 3 const description = 'This is a class for contact information' 4 var name = 'Nobody' 5 var address = 'Nowhere' 6 7 routine Contact( name : string, address = 'Unknown' ){ 8 self.name = name 9 self.address = address 10 } 11 routine Contact( another : Contact ){ 12 name = another.name 13 address = another.address 14 } 15 16 routine Show(){ io.writeln( name, 'lives at', address ) } 17 } 0.4 静态方法 静态方法可由在routine关键词前增加static关键词来实现。 这种方法可由类直接调用而不需要类实例 ,因此这种方法不能访问类的实例变量。 1 class Klass 2 { 3 var id = 123 4 static info = 'Klass' 5 static routine StaticMethod(){ id = 1 } # Wrong; 6 static routine StaticMethod(){ io.writeln( info ) } # Correct; 7 } 8 var obj = Klass::StaticMethod()