在消息传递模型里,

    1. 对象有属性,
    2. 并回应消息,
    3. 并从其父类继承属性与方法。

    当然了,我们知道 CLOS 使用的是通用函数模型。但本章我们只对于写一个迷你的对象系统 (minimal object system)感兴趣,而不是一个可与 CLOS 匹敌的系统,所以我们将使用消息传递模型。

    我们已经在 Lisp 里看过许多保存属性集合的方法。一种可能的方法是使用哈希表来代表对象,并将属性作为哈希表的条目保存。接着可以通过 来存取每个属性:

    1. (funcall (gethash 'move obj) obj 10)

    我们可以在这个概念上,定义一个 Smalltalk 风格的消息传递语法,

    所以想要一个对象 obj 移动 10 单位,我们可以说:

      事实上,纯 Lisp 唯一缺少的原料是继承。我们可以通过定义一个递归版本的 gethash 来实现一个简单版,如图 17.1 。现在仅用共 8 行代码,便实现了面向对象编程的 3 个基本元素。

      让我们用这段代码,来试试本来的例子。我们创建两个对象,其中一个对象是另一个的子类:

      1. > (setf circle-class (make-hash-table)
      2. (gethash :parent our-circle) circle-class
      3. (gethash 'radius our-circle) 2)

      circle-class 对象会持有给所有圆形使用的 area 方法。它是接受一个参数的函数,该参数为传来原始消息的对象:

      现在当我们询问 our-circle 的面积时,会根据此类所定义的方法来计算。我们使用 来读取一个属性,用 tell 来调用一个方法:

      1. > (rget 'radius our-circle)
      2. 2
      3. T
      4. > (tell our-circle 'area)

      的确有一个秘诀存在,但不是编程的奇技淫巧。这个秘诀是,Lisp 本来就是一个面向对象的语言了,甚至说,是种更通用的语言。我们需要做的事情,不过就是把本来就存在的抽象,再重新包装一下。