把LIST当做类,模拟面向对象编程
本帖最后由 vectra 于 2018-4-15 17:15 编辑众所周知,LISP是一种面向过程的函数式语言,下面探讨了一种面向对象风格的编程方法。
所谓代码即说明,话不多说,直接看实现。
(defun cls-get (cls name)
(cdr (assoc name cls))
)
(defun cls-new (name)
(list (cons "NAME" name))
)
(defun cls-new-line (p1 p2)
(append (cls-new "LINE")
(list(cons "P1" p1)
(cons "P2" p2)
(cons "DRAW"
'(lambda (cls)
(entmake (list
'(0 . "LINE")
(cons 10 (cls-get cls "P1"))
(cons 11 (cls-get cls "P2"))
)
)
)
)
(list "PROPERTIES" "NAME" "P1" "P2")
(list "METHOD" "DRAW")
)
)
)
(defun cls-new-circle (p r)
(append (cls-new "CIRCLE")
(list(cons "P" p)
(cons "R" r)
(cons "DRAW"
'(lambda (cls)
(entmake (list
'(0 . "CIRCLE")
(cons 10 (cls-get cls "P"))
(cons 40 (cls-get cls "R"))
)
)
)
)
(list "PROPERTIES" "NAME" "P" "R")
(list "METHOD" "DRAW")
)
)
)
(defun cls-get-name (cls)
(cls-get cls "NAME")
)
(defun cls-get-propert-names (cls)
(cls-get cls "PROPERTIES")
)
(defun cls-get-method-names (cls)
(cls-get cls "METHOD")
)
(defun cls-invoke-method (cls name)
(eval (list (cls-get cls name) 'cls))
)
下面来分别创建两个“类”。
(setq a(cls-new-line '(0 0) '(10 20))
b(cls-new-circle '(0 0) 30.)
)
_$ (cls-get-name a)
"LINE"
_$ (cls-get-name b)
"CIRCLE"
_$ (cls-get-propert-names a)
("NAME" "P1" "P2")
_$ (cls-get-propert-names b)
("NAME" "P" "R")
_$ (cls-get-method-names a)
("DRAW")
_$ (cls-get-method-names b)
("DRAW")
_$ (cls-invoke-method a "DRAW")
((0 . "LINE") (10 0 0) (11 10 20))
_$
_$ (cls-invoke-method b "DRAW")
((0 . "CIRCLE") (10 0 0) (40 . 30.0))
本帖最后由 vectra 于 2018-4-15 17:15 编辑
稍微多说几句,其实类也可以看做是一种数据结构,它包含了属性方法等。在LISP中,用LIST来存贮表示一个类是很自然提事情。
cls-new 函数可以看做是创建基类的过程,cls-new-line,cls-new-circle则分别创建了基于cls-new 的两个类。
cls-get-propert-names 返回了“类”中的属性名称列表,cls-get-method-names则返回了“类”中的方法列表
并且演示了(cls-invoke-method class "DRAW")来执行类中的方法,分别对对象 a,b执行DRAW方法,创建了各自的图形。
使用这种方法,可以统一编程接口,模拟了一些面向对象编程的特性,当然,只是模拟,LISP依旧是一种旧的面向过程的语言。
精辟!!!谢谢大师!!! 本帖最后由 fl202 于 2018-4-18 09:35 编辑
结构化程序设计从系统的功能入手,按照工程的标准和严格的规范将系统分解为若干功能模块,系统是实现模块功能的函数和过程的集合。由于用户的需求和软、硬件技术的不断发展变化,按照功能划分设计的系统模块必然是易变的和不稳定的。这样开发出来的模块可重用性不高。
面向对象程序设计从所处理的数据入手,以数据为中心而不是以服务(功能)为中心来描述系统。它把编程问题视为一个数据集合,数据相对于功能而言,具有更强的稳定性。
面向对象程序设计同结构化程序设计相比最大的区别就在于:前者首先关心的是所要处理的数据,而后者首先关心的是功能。
•面向过程:根据业务逻辑从上到下写垒代码
•函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
•面向对象:对函数进行分类和封装,它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。首先根据客户需求抽象出业务对象;然后对需求进行合理分层,构建相对独立的业务模块;之后设计业务逻辑,利用多态、继承、封装、抽象的编程思想,实现业务需求;最后通过整合各模块,达到高内聚、低耦合的效果,从而满足客户要求。
通常,使用函数式编程和面向对象编程方式来执行一个“方法”时,函数要比面向对象简便。总结:函数式的应用场景 --> 各个函数之间是独立且无共用的数据。
我个人感觉:面向对象编程方式适用于大程序,可重用性高,维护性高,需求变化后更改工作量小。
但对于lisp这种,函数式够用了。
这,跟面向对象编程 完全是两码事,不是名字取个new啥的就行了呀,
页:
[1]