Sway 参考手册/对象
在 Sway 世界中,对象是一个简单的相关变量集合。你已经接触过对象,虽然你可能没有意识到。当你创建一个变量时,你修改了环境,环境是一个对象。当你定义一个函数时,你创建了一个对象。要查看对象,我们使用预定义函数 pp 或 ppObject[1]。评估代码
function square(x) { x * x; } ppObject(square);
产生以下输出
<FUNCTION 3059>: context: <OBJECT 677> prior: :null filter: :null parameters: (x) code: { x * x; } name: square
我们看到 square 函数由六个 字段[2] 组成。这些字段是:context、prior、filter、parameters、code 和 name。
通常,对象允许你查看其各个组件。例如
println("square's parameters are: ",square . parameters);
产生
square's parameters are: (x)
我们使用函数 '.'(通常称为 点运算符)来提取对象的字段。
创建自己的对象很容易。首先,你必须创建一个 构造函数。构造函数只是一个返回 this 的函数。假设你想创建一个具有字段 name 和 age 的对象的构造函数。这是一种可能性
function person() { var name; var age; this; }
我们可以通过简单地调用构造函数来创建一个对象
var p = person();
变量 p 现在指向 person 对象,我们可以使用 p 和点运算符来设置 person 对象的字段
p . name = "Boris"; p . age = 33; inspect(p . name);
评估此代码产生以下输出
p . name is Boris
通常,在构造对象时为对象的字段提供初始值很方便。这是另一个版本的 person,它允许我们在创建对象时这样做
function person(name,age) { this; } var p = person("Boris",33); inspect(p . name);
输出相同
p . name is Boris
一般来说,如果要在一个对象被构造时初始化一个字段,就将该字段做成一个正式参数。如果不是,就将该字段做成一个局部声明的变量。
添加方法
[edit | edit source]对象也可以有方法[3]。以下是一个 person 构造函数的版本,它有一个 birthday 方法。
function person(name,age) { function birthday() { println("Happy Birthday, ",name,"!"); age = age + 1; } this; } var p = person("Boris",33); p . birthday(); inspect(p . age);
此代码的输出为
Happy Birthday, Boris! p . age is 34
总之,将函数变为构造函数,需要做以下事情:
this;
或者
return this;
作为函数的最后一行。局部变量(包括形式参数)成为函数的字段,而任何局部函数则作为方法。
对象和类型
[edit | edit source]如果你要问一个对象,“你是什么?”,它会回答,“我是一个对象!”。type 函数用于询问此类问题
var p = person("betty",19); inspect(type(p));
产生
type(p) is :OBJECT
虽然这在某些情况下有用,但通常我们想知道对象是什么类型的。例如,我们可能想知道 p 是否是一个 person 对象。一种方法是询问对象的构造函数它是否是 person 函数。幸运的是,所有对象都携带指向构造它们的函数的指针
var p = person("betty",19); inspect(p . constructor . name);
产生
p . constructor . name is person
因此,要询问 p 是否是 person,我们将使用表达式
if (p . constructor . name == :person) ...
由于这种结构相当冗长,因此有一个简单的函数,名为 is,你可以用它来代替
if (p is :person) ...
is 函数也适用于非对象。以下所有表达式均为真
3 is :INTEGER 3.4 is :REAL "hello" is :STRING :blue is :SYMBOL list(1,2,3) is :LIST array("a","b","c") is :ARRAY person("betty",19) is :OBJECT this is :OBJECT
is 函数也适用于绑定到值的变量。
面向对象的正式视图
[edit | edit source]Sway 是一种功能齐全的面向对象语言。这到底意味着什么?首先,如果一种编程语言具有以下三个特征,则它被认为是面向对象的
- 封装
- 继承
- 多态性
在这种意义上,封装意味着程序员可以将 数据 和 方法 打包成一个实体。我们已经看到 Sway 函数可以拥有局部变量和局部函数。因此,如果我们将局部变量(包括形式参数)视为数据,将局部函数视为方法,我们就会看到 Sway 可以在面向对象的意义上进行封装。
继承是另一种类型的对象可以使用另一种类型的对象的数据和方法,就好像它们最初是在另一个对象中定义的一样。
多态性意味着继承的对象似乎同时是两种类型的对象,它本身的类型和它继承的类型。我们将在后面的章节中更多地了解继承和多态性。
使用 objects 库
[edit | edit source]如果你包含 objects 库,你就可以向对象添加 toString 方法。然后,当你显示对象时,toString 方法被调用以帮助生成输出。
脚注
[edit | edit source]- ↑ 函数名称中的 pp 代表 pretty print,意思是漂亮地打印输出。
- ↑ 有些人使用术语 component 或 instance variable 来代替 field。此外,如果你尝试这样做,你可能会看到与 3059 和 677 不同的数字。
- ↑ 方法只是局部函数的另一种名称。