面向对象编程

面向对象编程

> LeekScript

欢迎阅读面向对象编程(OOP)文档,它讲的是如何创建类和对象来组织自己的代码。这个功能是从 LeekScript 2 开始加入的。

对象

对象是一种把多个值组合在一起的值,其中每个值都关联着一个名字。我们把这些值称为属性或字段。

创建对象

要创建一个对象,使用下面的语法:

在这个例子中,对象 objet 有两个属性:nom 和 age。

要创建一个空对象:

访问属性

点号 . 用来访问对象的某个属性:

还有另一种语法:objet["prop"],它可以用一个字符串值来访问属性:

修改属性

访问到一个属性之后,就可以像修改普通变量一样修改它:

比较对象

== 和 === 运算符只比较两个对象是不是同一个对象。即使两个对象拥有完全相同的属性,它们也会返回 false:

注意:从 LeekScript 4 开始 === 已被弃用,因为 == 本身就是严格比较(比如 null == 0 不再成立)。

属性列表

类

类是用来创建对象的模板。

定义类

我们这样定义一个类 Arme,它有 4 个字段,名字如下:

用类创建对象

其实 new 是可选的:类和函数很相似,可以直接调用它来创建一个对象:

用 .class 可以取得一个对象所属的类:

字段列表

instanceof

instanceof 关键字用来检查一个对象是不是某个类的实例:

构造函数

构造函数是定义在类里的一个函数,它可以根据一组参数来创建对象。构造函数这样定义:

构造函数的用法:

方法

方法是定义在类里的函数,可以在这个类的对象上使用。方法这样定义:

调用方法的语法如下:

objet["member"] 这种语法同样可用:

不建议使用它,出错的风险相当大。

> 注意:方法也可以使用注解

重载

只要改变参数的个数,就可以重载方法

之后就可以按需要用 1 个或 2 个参数来调用这个方法:

继承

继承这个概念可以用来建立类的层级关系。我们用 extends 关键字来写这种语法。这里的思路是声明一个“基类”,其他类可以在它的基础上构建。继承的类会得到基类的所有成员(变量)和方法(函数),并且可以重新定义它们,或者再添加新的成员和方法。

在这个例子中,父类 Item 有两个子类 Arme 和 Puce。Item 有 4 个成员(id、nom、cout 和 degats),它们在两个子类中都会存在。但 Puce 还有第 5 个字段 cooldown,这是芯片特有的。

如果把这三个对象都实例化并显示出来,就能看到每个类各自的成员:

我们的 Puce 类添加了一个 cooldown 成员,所以它只出现在自己的实例里,其他两个都没有!

继承而来的类和基类是同一种类型。 比如,如果一个对象是 Arme 类的实例,那么它同时也是 Item 类的实例:

继承的类同样会得到父类的方法。 调用父类的构造函数:

调用父类的方法:

如果重新定义一个方法时没有用 super 调用父类的方法,就会把原本的实现完全抹掉。

下面用一个小例子快速总结一下:

访问级别

可以给类的每个成员设定访问级别。一共有 3 种访问级别:public(默认)、protected 和 private。

静态成员

静态成员(字段或方法)属于类本身,而不属于类的某个对象。

静态字段只会初始化一次(在第一个回合),和全局变量一样。

定义一个静态字段:

静态方法:

final 属性

要表示类的某个成员不可修改、只能读取,可以使用 final 关键字。这样的成员只能在定义处或构造函数中初始化。

string() 方法

如果一个类里有 string() 函数,那么当这个对象需要被转换成字符串时,就会自动调用它:

> 注意:可以给 string 方法定义带默认值的参数,不过在字符串拼接时,这个方法会在不传任何参数的情况下被调用

> 注意 2:当一个类没有 string() 方法时,如果它有父类,就会使用父类的方法。因此,与其把类名写死,不如使用 this.class.name,这往往更方便。