面向对象
在多数 OOP 系统中,方法属于类。在 Common Lisp 中,方法是通用函数的实例,这些函数不仅可以分派到第一个参数,还可以分派到每个参数。这意味着函数,而不是类,是主要的驱动力。
通用函数和方法
我们使用 defgeneric
声明一个通用函数
(defgeneric description (object)
(:documentation "Return a description of an object."))
我们使用 defmethod
声明该函数的方法
(defmethod description ((object integer))
(format nil "The integer ~D" object))
(defmethod description ((object float))
(format nil "The float ~3,3f" object))
我们可以在 REPL 中测试它们
CL-USER> (description 10)
"The integer 10"
CL-USER> (description 3.14)
"The float 3.140"
类
(defclass vehicle ()
((speed :accessor vehicle-speed
:initarg :speed
:type real
:documentation "The vehicle's current speed."))
(:documentation "The base class of vehicles."))
当超类列表为空时,使用默认基类 standard-class
。你可以更改它,但这是一项高级主题。
(defclass bicycle (vehicle)
((mass :reader bicycle-mass
:initarg :mass
:type real
:documentation "The bike's mass."))
(:documentation "A bicycle."))
(defclass canoe (vehicle)
((rowers :reader canoe-rowers
:initarg :rowers
:initform 0
:type (integer 0)
:documentation "The number of rowers."))
(:documentation "A canoe."))
实例化
CL-USER> (defparameter canoe (make-instance 'canoe
:speed 10
:rowers 6))
CANOE
CL-USER> (class-of canoe)
#<STANDARD-CLASS COMMON-LISP-USER::CANOE>
CL-USER> (canoe-rowers canoe)
6
CL-USER> (vehicle-speed canoe)
10
我们可以使用 describe
获取有关类的信息
CL-USER> (describe 'canoe)
COMMON-LISP-USER::CANOE
[symbol]
CANOE names the standard-class #<STANDARD-CLASS
COMMON-LISP-USER::CANOE>:
Documentation:
A canoe.
Direct superclasses: VEHICLE
No subclasses.
Not yet finalized.
Direct slots:
ROWERS
Type: (INTEGER 0)
Initargs: :ROWERS
Initform: 0
Readers: CANOE-ROWERS
Documentation:
The number of rowers.