在这篇文章中,勇敢的人希望(在 C++ 中)将类型对象向下转换为Base
类型Derived
。假设 Derived 类型的属性不超过,如果您嫉妒该类提供的额外方法Base
,这可能是有道理的。Derived
是否有允许这种事情的编程语言?
在这篇文章中,勇敢的人希望(在 C++ 中)将类型对象向下转换为Base
类型Derived
。假设 Derived 类型的属性不超过,如果您嫉妒该类提供的额外方法Base
,这可能是有道理的。Derived
是否有允许这种事情的编程语言?
实际上,这在 Common Lisp 和其他移植了 CLOS(Common Lis Object System)的 Lisp 方言中是毫无问题的。您change-class
为此使用通用函数。
CLOS 与多个调度方法一起工作,因此方法不与类或对象绑定,它只是在一组类似函数中选择的函数,WRT 与其参数的类型(或身份)相同。使用 时change-class
,您可以像创建新实例一样提供参数,并且已经存储在对象中的数据将保留。这是一个小会话,展示了它是如何工作的:
CL-USER> (defclass base ()
((name :initarg :name)))
#<STANDARD-CLASS BASE>
CL-USER> (defclass derived (base)
((age :initarg :age :initform 0)))
#<STANDARD-CLASS DERIVED>
CL-USER> (defvar foo (make-instance 'base :name "John Doe"))
FOO
CL-USER> (change-class foo 'derived :age 27)
#<DERIVED {100338F2D1}>
CL-USER> (with-slots (name age) foo
(list name age))
("John Doe" 27)
CL-USER> (defvar bar (make-instance 'base :name "Baby Joe"))
BAR
CL-USER> (change-class bar 'derived)
#<DERIVED {10036CF6E1}>
CL-USER> (with-slots (name age) bar
(list name age))
("Baby Joe" 0)
CL-USER>
如果这个默认行为还不够,你可以在update-instance-for-different-class
.
所以,是的,有一些编程语言允许这样的事情!
不,但首先这样做是一种强烈的代码气味。
一种更好的选择是使用装饰器模式,这正是它的目的。
如果Derived
不添加任何属性,那么它添加的方法必须在它从Base
. 在那种情况下,为什么不把这些方法移到Base
它们所属的地方呢?