この投稿Base
では、勇敢な人が(C ++で)型のオブジェクトを型にダウンキャストしたいと考えていますDerived
。Derived型に。よりも多くの属性がないと仮定すると、クラスが提供する追加のメソッドに嫉妬している場合は意味がありBase
ます。Derived
そのようなことを可能にするプログラミング言語はありますか?
この投稿Base
では、勇敢な人が(C ++で)型のオブジェクトを型にダウンキャストしたいと考えていますDerived
。Derived型に。よりも多くの属性がないと仮定すると、クラスが提供する追加のメソッドに嫉妬している場合は意味がありBase
ます。Derived
そのようなことを可能にするプログラミング言語はありますか?
実際、これはCommon Lispや、CLOS(Common Lis Object System)が移植された他のLisp方言で問題なく行われていることです。change-class
そのためにジェネリック関数を使用します。
CLOSは複数のディスパッチメソッドで動作するため、メソッドはクラスやオブジェクトに関連付けられていません。引数のタイプ(またはID)と同様の関数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
その場合、それらのメソッドをそれらが属する場所に移動しないのはなぜですか?