9

この質問が多く寄せられていることは承知していますが、私の見解では、通常の回答は満足のいくものとはほど遠いものです。

次のクラス階層が与えられた場合:

class SuperClass{}
class SubClass extends SuperClass{}

サブクラスをインスタンス化するために、なぜ人々はこのパターンを使用するのですか?

SuperClass instance = new SubClass();

これの代わりに:

SubClass instance = new SubClass();

さて、私が見る通常の答えは、これは、次instanceのような SuperClass のインスタンスを必要とするメソッドに引数として送信するためであるというものです。

void aFunction(SuperClass param){}

//somewhere else in the code...
...
aFunction(instance);
...

しかし、それを保持する変数の型に関係なく、SubClass のインスタンスを aFunction に送信できます! つまり、次のコードはエラーなしでコンパイルおよび実行されます (以前に提供された aFunction の定義を前提としています)。

SubClass instance = new SubClass();
aFunction(instance);

実際、私の知る限り、変数の型は実行時には意味がありません。それらはコンパイラによってのみ使用されます!

変数を SuperClass として定義する別の考えられる理由は、いくつかの異なるサブクラスがあり、変数が実行時にそれらのいくつかへの参照を切り替えることになっている場合ですが、たとえば、これがクラスで発生するのを見ただけです (スーパーではなく、サブではありません.ちょうどクラス)。一般的なパターンを必要とするのは間違いなく十分ではありません...

4

5 に答える 5

8

このタイプのコーディングの主な議論は、 がタイプ のサブタイプである場合、 の任意のインスタンスを と交換できるべきであると述べているリスコフ置換原理によるものです。XTTX

これの利点は単純です。次のようなプロパティ ファイルを持つプログラムがあるとします。

mode="Run"

プログラムは次のようになります。

public void Program
{
    public Mode mode;

    public static void main(String[] args)
    {
        mode = Config.getMode();
        mode.run();
    }
}

簡単に言うと、このプログラムは構成ファイルを使用して、このプログラムが起動するモードを定義します。Configクラスでは、次のgetMode()ようになります。

public Mode getMode()
{
    String type = getProperty("mode"); // Now equals "Run" in our example.

    switch(type)
    {
       case "Run": return new RunMode();
       case "Halt": return new HaltMode();  
    }
}

そうしないとなぜこれが機能しないのか

これで、 type の参照があるためMode、プロパティの値を変更するだけで、プログラムの機能を完全に変更できmodeます。をお持ちpublic RunMode modeの場合、このタイプの機能を使用することはできません。

なぜこれが良いことなのか

このパターンは、プログラムの拡張性を広げるため、非常に人気があります。これは、作成者がこの種の機能を実装したい場合、この種の望ましい機能が最小限の変更で可能であることを意味します。そして、つまり、さあ。コードを 1 行も編集せずに、構成ファイル内の 1 つの単語を変更するだけで、プログラム フローを完全に変更できます。それは望ましいことです。

于 2013-10-01T10:12:19.927 に答える
0

これは設計の観点からのもので、1 つのスーパー クラスがあり、機能を拡張する複数のサブクラスが存在する可能性があります。

サブクラスを作成する必要がある実装者は、どのメソッドをオーバーライドするかだけに集中する必要があります

于 2013-10-01T10:05:07.247 に答える