0

次の質問に対する答えがすべての主要な OOP 言語で同じかどうかを理解しようとしています。そうでない場合、それらの言語はどのように異なりますか。

メソッドと;Aを定義するクラスがあるとします。メソッドは メソッドを呼び出します。のサブクラスオーバーライド メソッド(つまり、適切な構文を使用して、が呼び出されるたびにクラス内の実装が使用されるようにします)。actjumpactjumpABjumpjumpB

b私はクラスのオブジェクトを持っていますB。それが class であるかのように正確に動作するようにしますAjumpつまり、の実装を使用して を実行したいのですA。さまざまな言語でのオプションは何ですか?

たとえば、何らかの形式のダウンキャストでこれを達成できますか? または、呼び出すメソッドを認識しているプロキシ オブジェクトを作成することでしょうか?

クラスの新しいオブジェクトを作成し、 と の間でA内部状態の共有を慎重に設定することは避けたいと思います。これは、明らかに将来性がなく、複雑であるためです。また、コピーするデータが大量にある可能性があるため、の状態をクラスの新しいオブジェクトにコピーすることも避けたいと思います。abbA

アップデート

私は特に Python についてこの質問をしましたが、これは Pythonで達成することは不可能であり、技術的には可能だと思われます...ちょっと..

技術的な実現可能性は別として、設計の観点からこれを行うことに反対する強い議論があるようです。それについては別の質問で尋ねています。

4

4 に答える 4

2

コメントは繰り返しました: 継承よりも構成を優先します。

サブクラスがスーパークラスと明確に定義された動作の違いを持っ​​ている場合、継承はうまく機能しますが、そのモデルがぎこちなくなったり意味をなさなくなったりする点に頻繁に遭遇します。その時点で、設計を再検討する必要があります。

通常、コンポジションはより良い解決策です。オブジェクトのさまざまな動作を別のオブジェクト (または複数のオブジェクト) に委譲すると、サブクラス化の必要性が軽減または排除される場合があります。

あなたの場合、クラス A とクラス B の動作の違いは、戦略パターンにカプセル化できます。次に、新しい戦略を割り当てるだけで、インスタンス レベルでクラス A (および必要に応じてクラス B) の動作を変更できます。

Strategy パターンは、短期的にはより多くのコードを必要とするかもしれませんが、クリーンで保守しやすいものです。メソッドの入れ替え、モンキー パッチ、および特定の言語の実装をいじることができるこれらすべての優れた機能は楽しいものですが、予期しない副作用の可能性が高く、コードの保守が困難になる傾向があります。

于 2012-01-17T16:39:18.633 に答える
1

あなたが求めていることは、OOPプログラミングとはまったく関係がありません/サポートされていません。

オブジェクトAをクラスでサブクラス化し、Bそのメソッドをオーバーライドする場合、具体的なインスタンスBが作成されると、基本メソッドのオーバーライドされた/新しい実装がすべて関連付けられます (仮想テーブルを使用した Java または C++ などについて話します)。

オブジェクト をインスタンス化しBました。
そのメソッドをオーバーライドした場合、スーパークラスのメソッドを呼び出すことができる/できる/できると期待するのはなぜですか?

もちろん、メソッド内で呼び出すなどして明示的に呼び出すこともできsuperますが、自動的に行うことはできず、キャストもそれを行うのに役立ちません。

なぜあなたがそれをしたいのか想像できません。
class を使用する必要がある場合は、 classAを使用しますA
その機能をオーバーライドする必要がある場合は、そのサブクラスを使用してBください。

于 2012-01-16T21:13:40.430 に答える
0

ほとんどのプログラミング言語は、仮想関数の動的ディスパッチ (jump親クラスの実装ではなくサブクラスでオーバーライドされたメソッドを呼び出す場合) をサポートするために、何らかの問題を抱えています。一般に、特殊化/ポリモーフィズムは望ましい機能です。おそらく、そもそも OOP の目標です。

Virtual Functionsに関するウィキペディアの記事を参照してください。多くのプログラミング言語での仮想関数のサポートの有用な概要が説明されています。これは、特定の言語を検討する際の出発点となるだけでなく、プログラマーがディスパッチの動作を制御できる言語を検討する際に考慮すべきトレードオフも提供します (たとえば、C++ のセクションを参照してください)。

大まかに言えば、あなたの質問に対する答えは、「いいえ、すべてのプログラミング言語で動作が同じというわけではありません」です。さらに、言語に依存しないソリューションはありません。動作が必要な場合は、C++ が最適です。

于 2012-01-16T21:16:42.113 に答える
0

これは実際に Python (一種の) で行うことができますが、いくつかのひどいハックがあります。最初の Python 固有の質問で説明したラッパーのようなものを B のサブクラスとして実装する必要があります。次に、書き込みプロキシも実装する必要があります (ラッパー オブジェクトには、通常はクラス階層に関連付けられている状態が含まれていてはならず、すべての属性アクセスを基になる B のインスタンスにリダイレクトする必要があります。

ただし、メソッド ルックアップを A にリダイレクトしてから、ラップされたインスタンスでメソッドを呼び出すのではなく、ラッパー オブジェクトを として渡してメソッドを呼び出しますself。ラッパー クラスは B のサブクラスであるため、これは正当です。したがって、ラッパー インスタンスは、呼び出しているメソッドを持つクラスのインスタンスです。

これは非常に奇妙なコードであり、IS-A と HAS-A の両方の関係を同時に使用してクラスを動的に生成する必要があります。それはおそらくかなり壊れやすく、多くのまれなケースで奇妙な結果をもたらすでしょう (この種の奇妙なことが可能であるという理由だけで、Python で 100% 完璧なラッパー クラスを書くことは通常不可能です)。

私は天気を完全に脇に置きます。これは良い考えかどうかです。

于 2012-01-16T23:45:48.693 に答える