5

オブジェクト指向プログラミングでは、作成済みのオブジェクトの動作を変更できると便利な場合があります。もちろん、これは戦略パターンなどの比較的冗長な手法で行うことができます。ただし、インスタンス化後に vtable ポインターを変更して、オブジェクトの型を完全に変更した方がよい場合もあります。クラスAからクラスBに切り替えると仮定すると、これは安全です:

  1. クラス B はクラス A のサブクラスであり、新しいフィールドを追加しない、または
  2. クラス B とクラス A は同じ親クラスを持ちます。親クラスの仮想関数をオーバーライドする以外は何もしません。(新しいフィールドや仮想関数はありません。)
  3. いずれの場合も、A と B は同じ不変条件を持たなければなりません。

これは、C++ および D プログラミング言語でハック可能です。ポインターを任意にキャストできるためです。これを行う高レベルの方法が一般的に提供されていないのはなぜですか?

4

5 に答える 5

3

ほとんどの言語デザイナーの考え方はあまりにも静的だからです。

このような機能はプログラマーにとって危険ですが、ライブラリビルダーにとって必要なツールです。たとえば、Javaでは、コンストラクターを呼び出さなくてもオブジェクトを作成できますが(はい、できます!)、この機能はライブラリ設計者にのみ与えられます。ただし、それでも、ライブラリ設計者が殺すであろう多くの機能は、残念ながらJavaでは不可能です。一方、C#は、各バージョンでますます動的な機能を追加しています。今後のDLR(動的言語ランタイム)を使用して構築できるすべての素晴らしいライブラリを本当に楽しみにしています。

Smalltalkなどの一部の動的言語(および私が知る限り、PerlとPythonは知っていますが、Rubyはそうではありません)では、オブジェクトのクラスを変更することは完全に可能です。Pharo Smalltalkでは、これを次のように実現します。

object primitiveChangeClassTo: anotherObject

objectのクラスを。のクラスに変更しanotherObjectます。object become: anotherObjectこれは、両方のオブジェクトのすべてのポインタを交換するものと同じではないことに注意してください。

于 2009-12-20T17:10:08.390 に答える
2

__class__instance属性を変更することで、Python でそれを行うことができます。

>>> class A(object):
...     def foo(self):
...         print "I am an A"
...
>>>
>>> class B(object):
...     def foo(self):
...         print "I am a B"
...
>>>
>>> a = A()
>>> a.foo()
I am an A

>>> a.__class__
<class '__main__.A'>

>>> a.__class__ = B
>>>
>>> a
<__main__.B object at 0x017010B0>
>>> a.foo()
I am a B

しかし、12 年間の Python プログラミングの中で、私はそれを使用したことがなく、他の誰かが使用しているのを見たこともありません。私見では、この機能を何気なく使用すると、コードの保守とデバッグが困難になるという大きな危険があります。

私がそれを使用することを想像できる唯一の状況は、実行時のデバッグです。たとえば、作成を制御できないクラスのインスタンスをモックオブジェクトまたはログで装飾されたクラスに変更する場合などです。プロダクションコードでは使用しません。

于 2009-12-20T19:01:26.017 に答える
1

XoTclのドキュメントを言い換えると、「オブジェクト指向」であると宣言するほとんどの言語はクラス指向ではないためです。XoTclミックスイン、Rubyミックスイン、およびPerl6ロールが、探している機能を提供しているようです。

于 2009-12-20T18:29:16.270 に答える
1

これは高水準言語で行うことができます - Smalltalk の「become」メッセージを参照してください。この機能を ST でも正しく使用することはほとんど不可能であるという事実が、C++ のような静的に型付けされた言語がこの機能をサポートしていない理由である可能性があります。

于 2009-12-20T16:41:09.817 に答える
0

あなたが話しているのは、いくつかの高レベルの動的言語で利用可能なモンキーパッチです。

モンキー パッチ (monkey-patch、MonkeyPatch とも呼ばれる) は、元のコードを変更することなく、動的言語 (Smalltalk、JavaScript、Objective-C、Ruby、Perl、Python、Groovy など) のランタイム コードを拡張または変更する方法です。ソースコード。

于 2009-12-20T16:55:51.413 に答える