2012-01-23 6 views
4

recommended principles of object-oriented programmingのうちの1つは、Liskov substitution principleです。サブクラスは基本クラスと同じように動作する必要があります(警告:これはLiskovの原則の正しい記述ではありません:PSを参照)。クラス継承:コンストラクタは互換性がありますか?多重継承の場合?

コンストラクタにも適用することをお勧めしますか?私は主にPythonを念頭に置いていますが、その方法は__init__()ですが、この質問は継承を伴うオブジェクト指向言語に適用されます。

いくつかの素晴らしいデフォルトの動作(Pythonのディクショナリを継承しているので、obj['key']が新しいクラスのオブジェクトに対して機能するようなもの)を提供する1つ以上のクラスから継承することが有用なことがあるので、 )。ただし、サブクラスを辞書のように正確に使用できるようにすることは、必ずしも自然でも簡単でもありません。コンストラクタのパラメータは、特定のユーザサブクラス(たとえば、シリアルポートのセットを表すクラスports['usb1']がUSBポート#1などの辞書のように動作したい場合があります)。このような状況に対して推奨されるアプローチは何ですか?それらの基本クラスのものと完全に互換性のあるサブクラスのコンストラクタを持ち、簡単で使いやすいパラメータを取るオブジェクトファクトリ関数を通じてインスタンスを生成しますか?または、その基本クラスのコンストラクタに直接渡すことはできないが、ユーザの観点からすれば論理的なクラスコンストラクタを書くだけです。

PS:私は上記の、リスコフ原理を誤解:スヴェンさんのコメントは以下のオブジェクトサブクラスのがスーパークラス(自身がスーパークラスのように動作する必要はありませんサブクラスのオブジェクトのように振る舞うべきという事実を指摘します。特に、それらのコンストラクタは同じパラメータ(シグネチャ)を持つ必要はありません。

+1

@SvenMarnach:あなたのコメントは、受け入れられる回答でなければなりません。 –

+0

@SvenMarnach:+1:良い点、確かに。あなたが答えをアップアップするのは嬉しいです。あなたが私の主な尋問の一つに答えたので、私はそれを受け入れられるものとしてマークするかもしれません。 – EOL

答えて

4

リクエストに応じて、私はこれまでにコメントされていたものを回答として掲示します。

リンクされたWikipediaの記事で定義されている原則は、「SがTのサブタイプであれば、タイプTのオブジェクトはタイプSのオブジェクトで置き換えられます。 「サブクラスは基本クラスと同じように動作する」とは解釈されません。違いはコンストラクタを考えるときに重要です。Wikipediaのバージョンでは、型自体ではなく、サブタイプのオブジェクトについてしか話しません。オブジェクトの場合、コンストラクタはすでに呼び出されているため、コンストラクタには適用されません。これはまた、私がそれを適用する方法、および標準libに適用される方法(例:defaultdictおよびdict)です。

複数の継承のコンストラクタは、おそらく言語に依存しない方法で議論することはできません。 Pythonには、2つのアプローチがあります。継承ダイアグラムにダイヤモンドパターンが含まれていて、すべてのコンストラクタが正確に1回呼び出されるようにする必要がある場合は、super()を使用し、Raymond Hettingerの記事Python's super() considered superのセクション「実用的なアドバイス」のパターンに従ってください。ダイヤモンドを持たない場合(objectを含むものを除く)、すべての基本クラスのコンストラクタに対して明示的な基本クラス呼び出しを使用することもできます。