跳转到内容

Sway 参考手册/对象

来自维基教科书,开放的书籍,开放的世界

在 Sway 世界中,对象是一个简单的相关变量集合。你已经接触过对象,虽然你可能没有意识到。当你创建一个变量时,你修改了环境,环境是一个对象。当你定义一个函数时,你创建了一个对象。要查看对象,我们使用预定义函数 ppppObject[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] 组成。这些字段是:contextpriorfilterparameterscodename

通常,对象允许你查看其各个组件。例如

   println("square's parameters are: ",square . parameters);

产生

   square's parameters are: (x)
   

我们使用函数 '.'(通常称为 点运算符)来提取对象的字段。

创建自己的对象很容易。首先,你必须创建一个 构造函数。构造函数只是一个返回 this 的函数。假设你想创建一个具有字段 nameage 的对象的构造函数。这是一种可能性

   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 是一种功能齐全的面向对象语言。这到底意味着什么?首先,如果一种编程语言具有以下三个特征,则它被认为是面向对象的

  1. 封装
  2. 继承
  3. 多态性

在这种意义上,封装意味着程序员可以将 数据方法 打包成一个实体。我们已经看到 Sway 函数可以拥有局部变量和局部函数。因此,如果我们将局部变量(包括形式参数)视为数据,将局部函数视为方法,我们就会看到 Sway 可以在面向对象的意义上进行封装。

继承是另一种类型的对象可以使用另一种类型的对象的数据和方法,就好像它们最初是在另一个对象中定义的一样。

多态性意味着继承的对象似乎同时是两种类型的对象,它本身的类型和它继承的类型。我们将在后面的章节中更多地了解继承和多态性。

使用 objects

[edit | edit source]

如果你包含 objects 库,你就可以向对象添加 toString 方法。然后,当你显示对象时,toString 方法被调用以帮助生成输出。

脚注

[edit | edit source]
  1. 函数名称中的 pp 代表 pretty print,意思是漂亮地打印输出。
  2. 有些人使用术语 componentinstance variable 来代替 field。此外,如果你尝试这样做,你可能会看到与 3059 和 677 不同的数字。
  3. 方法只是局部函数的另一种名称。


数组和列表 · 继承

华夏公益教科书