跳轉到內容

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. 方法只是區域性函式的另一種名稱。


陣列和列表 · 繼承

華夏公益教科書