明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1845|回复: 4

[经验] 把LIST当做类,模拟面向对象编程

[复制链接]
发表于 2018-4-15 09:29:07 | 显示全部楼层 |阅读模式
本帖最后由 vectra 于 2018-4-15 17:15 编辑

众所周知,LISP是一种面向过程的函数式语言,下面探讨了一种面向对象风格的编程方法。

所谓代码即说明,话不多说,直接看实现。

  1. (defun cls-get (cls name)
  2.   (cdr (assoc name cls))
  3. )

  4. (defun cls-new (name)
  5.   (list (cons "NAME" name))
  6. )


  7. (defun cls-new-line (p1 p2)
  8.   (append (cls-new "LINE")
  9.     (list  (cons "P1" p1)
  10.     (cons "P2" p2)

  11.     (cons "DRAW"
  12.           '(lambda (cls)
  13.       (entmake (list
  14.            '(0 . "LINE")
  15.            (cons 10 (cls-get cls "P1"))
  16.            (cons 11 (cls-get cls "P2"))
  17.          )
  18.       )
  19.           )
  20.     )
  21.     (list "PROPERTIES" "NAME" "P1" "P2")
  22.     (list "METHOD" "DRAW")
  23.     )
  24.   )
  25. )

  26. (defun cls-new-circle (p r)
  27.   (append (cls-new "CIRCLE")
  28.     (list  (cons "P" p)
  29.     (cons "R" r)

  30.     (cons "DRAW"
  31.           '(lambda (cls)
  32.       (entmake (list
  33.            '(0 . "CIRCLE")
  34.            (cons 10 (cls-get cls "P"))
  35.            (cons 40 (cls-get cls "R"))
  36.          )
  37.       )
  38.           )
  39.     )

  40.     (list "PROPERTIES" "NAME" "P" "R")
  41.     (list "METHOD" "DRAW")
  42.     )
  43.   )
  44. )

  45. (defun cls-get-name (cls)
  46.   (cls-get cls "NAME")
  47. )

  48. (defun cls-get-propert-names (cls)
  49.   (cls-get cls "PROPERTIES")
  50. )

  51. (defun cls-get-method-names (cls)
  52.   (cls-get cls "METHOD")
  53. )

  54. (defun cls-invoke-method (cls name)
  55.   (eval (list (cls-get cls name) 'cls))
  56. )



下面来分别创建两个“类”。
  1. (setq a  (cls-new-line '(0 0) '(10 20))
  2.       b  (cls-new-circle '(0 0) 30.)
  3. )


_$ (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))




"觉得好,就打赏"
还没有人打赏,支持一下
 楼主| 发表于 2018-4-15 09:36:37 | 显示全部楼层
本帖最后由 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依旧是一种旧的面向过程的语言。
发表于 2018-4-16 17:11:45 | 显示全部楼层
精辟!!!谢谢大师!!!
发表于 2018-4-16 17:38:30 | 显示全部楼层
本帖最后由 fl202 于 2018-4-18 09:35 编辑

       结构化程序设计从系统的功能入手,按照工程的标准和严格的规范将系统分解为若干功能模块,系统是实现模块功能的函数和过程的集合。由于用户的需求和软、硬件技术的不断发展变化,按照功能划分设计的系统模块必然是易变的和不稳定的。这样开发出来的模块可重用性不高。
  面向对象程序设计从所处理的数据入手,以数据为中心而不是以服务(功能)为中心来描述系统。它把编程问题视为一个数据集合,数据相对于功能而言,具有更强的稳定性。
面向对象程序设计同结构化程序设计相比最大的区别就在于:前者首先关心的是所要处理的数据,而后者首先关心的是功能。
•  面向过程:根据业务逻辑从上到下写垒代码
•  函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
•  面向对象:对函数进行分类和封装,它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。首先根据客户需求抽象业务对象;然后对需求进行合理分层,构建相对独立的业务模块;之后设计业务逻辑,利用多态继承封装、抽象的编程思想,实现业务需求;最后通过整合各模块,达到高内聚、低耦合的效果,从而满足客户要求。

    通常,使用函数式编程和面向对象编程方式来执行一个“方法”时,函数要比面向对象简便。总结:函数式的应用场景 --> 各个函数之间是独立且无共用的数据。

    我个人感觉:面向对象编程方式适用于大程序,可重用性高,维护性高,需求变化后更改工作量小。
                       但对于lisp这种,函数式够用了。

发表于 2018-4-17 06:55:29 | 显示全部楼层
这,跟面向对象编程 完全是两码事,不是名字取个new啥的就行了呀,
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-5-9 16:05 , Processed in 0.167934 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表