In this post, a brave wants (in C++) to downcast a object of type Base
to a Derived
type. Assuming that the Derived type has no more attributes than Base
, it can make sense if you're jealous of the extra methods that the Derived
class provides.
Are there programming languages that allow such a thing?
Actually, this is something that is done without problem in Common Lisp, and in other Lisp dialects where CLOS (Common Lis Object System) was ported. You use the change-class
generic function for that.
CLOS works with multiple dispatch methods, so a method is not tied to a class or object, it's just a function that is chosen in a group of similar functions WRT to the types (or identities) of its arguments. When using change-class
, you can give arguments as if you were creating a new instance, and data already stored in the object will remain. Here is a little session that shows how it works:
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>
If this default behaviour is not enough, you may define a method on update-instance-for-different-class
.
So yeah, there are programming languages that allow such a thing!