被各种琐事耽搁了,谈一下迟来的对象。这个对象跟见到过的都有点不一样。
Lisp 是面向对象的,它的对象跟其他常见语言(如 Python 和 Java)中的对象有挺大不同,但都是基于类的,即所有对象都是一个特定类的实例。不像 Python 或 Java 把一个对象的所有东西放在一个类里,Lisp 把对象的数据部分和操作部分分开了。数据部分定义在类里,称为槽(slot)。对对象的操作由广义函数(generic function)和方法(method)共同实现。
假设现在有「人」这个类,有两个槽,用于存放名字和年龄,定义如下:
槽是每个实例中可以存放值的位置。想要访问一个实例化的对象的槽,这个对象的槽必须被设置了值才能访问,否则会报错(如上面的 name 槽实例化对象后未设置初值时)。在定义类时,可以使用槽描述符给一个槽设置初值。
广义函数只是定义抽象操作,具体的实现由方法来完成。一个广义函数可以对应多个方法(多重方法),每个方法都定义了广义函数的部分实现,并且参数需要对应。如「人」可以吃东西,而怎么吃则由方法来实现,比如定义一个倒着吃的方法。 这个方法只能「人」倒着吃,而其他动物的类也能,那么同样可以定义一个其他动物倒着吃的方法,参数同样跟广义函数一样。也就是说具体的「吃」方法不对人或其他动物负责(类),只对广义函数负责。
Lisp 支持多继承。字面意义上的继承。如人可以继承猩猩和猴子。相同的东西(槽)合并,不同的东西就独立继承。
比起一些其他面向对象语言,Lisp 的对象的操作复杂了不少,各种方法组合虽然强大,但也很需要精力去熟悉。快过年了,只能谈这个对象了。真正的深入对象,还有很长的路。
领取专属 10元无门槛券
私享最新 技术干货