首页 > 代码库 > newLISP FOOP 对象模型

newLISP FOOP 对象模型


对象之间的关系

对象可以包含对象,就像一般面向对象的对象树一样。在lisp中,其实很简单, 因为对象就是list, 对象包含对象也就是list里面包含list,此嵌套关系可以有很多层。

下面这个例子同样来自manual

; create classes
(new Class ‘Person)
(new Class ‘Address)
(new Class ‘City)
(new Class ‘Street)

; create an object containing other objects
(set ‘JohnDoe (Person (Address (City "Boston") (Street 123 "Main Street"))))
→ (Person (Address (City "Boston") (Street 123 "Main Street")))


类的继承

可以用new来创建某个类的子类

比如下面的代码:

> (new Class ‘Bird)
Bird
> (new Bird ‘Hawk)
Hawk


Hawk是Bird的子类,但是注意,这种继承关系非常弱。如果现在为Bird添加方法fly,Hawk是不知道的,除非你再次用new。
> (define (Bird:fly) (println "bird fly"))
(lambda () (println "bird fly"))
> (Hawk:fly)

ERR: invalid function : (Hawk:fly)
> (Bird:fly)
bird fly
"bird fly"
> (new Bird ‘Hawk true)
Hawk
> (Hawk:fly)
bird fly
"bird fly"
> 

查看API文档关于new的部分,发现这种继承其实是通过复制context来实现的。因此当时复制的时候Bird还没有fly, Hawk也就没有。Bird后来添加了fly方法,必须再次用new来复制一次。true参数强制用Bird的symbol覆盖原来Hawk中同名的symbol.


用FOOP构造大型程序

1. 首先是分模块编写,将类的代码按照context的写法放到不同的文件中,此举和写context没太大区别,不过在创建symbol前用类名加冒号前缀。

2. 在调用代码的地方,要用(new Class ..来创建类,之后就可以用前面介绍的调用类的方法。下面的例子来自于manual

这是调用代码:

; file MAIN.lsp - declare all classes used in MAIN

(new Class ‘Rectangle)
(new Class ‘Circle)

; start up code

(load "Rectangle.lsp")
(load "Circle.lsp")

; main control code

; end of file
Rectangle和Circle都放在各自的lsp文件中:
; file Rectangle.lsp - class methods for rectangles

(context Rectangle)

(define (Rectangle:area)
(mul (self 3) (self 4)))

(define (Rectangle:move dx dy)
(inc (self 1) dx) 
(inc (self 2) dy))

; end of file

; file Circle.lsp - class methods for circles

(context Circle)

(define (Circle:area)
    (mul (pow (self 3) 2) (acos 0) 2))

(define (Circle:move dx dy)
    (inc (self 1) dx) 
    (inc (self 2) dy))

; end of file


有一段视频介绍了FOOP,链接地址:http://neglook.com/movies/what-the-foop-H264.mov







newLISP FOOP 对象模型