Какие языки позволяют изменять идентичность объекта (не приведенного)? [закрытый]
В этом посте храбрец хочет (в C++) понизить объект типа Base
до типа Derived
. Предполагая, что производный тип имеет не больше атрибутов, чем Base
, он может иметь смысл, если вы завидуете дополнительным методам, которые предоставляет класс Derived
.
Существуют ли языки программирования, которые позволяют такое?
3 ответа:
На самом деле, это то, что делается без проблем в Common Lisp, и в других диалектах Lisp, где CLOS (Common Lis Object System) был портирован. Вы используете
CLOS работает с несколькими методами диспетчеризации, поэтому метод не привязан к классу или объекту, это просто функция, которая выбирается в группе аналогичных функций WRT для типов (или тождеств) ее аргументов. При использованииchange-class
родовая функция для этого.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
.Так что да, есть языки программирования, которые позволяют такое!
Нет, но это сильный запах кода, чтобы сделать это в первую очередь.
Лучшей альтернативой является использование шаблона декоратора, это именно то, для чего он был создан.