3

親クラスとしてクラスAがあり、それを拡張するクラスCがあるとします。

class A
{
    void m()
    {
        System.out.println("A.m");
    }
}

class C extends A
{
    @Override
    void m()
    {
        System.out.println("C.m");
    }
}

A a参照とC c、それらを使用して同じオブジェクトタイプを指す場合、たとえばA a = new C();との違いは何C c = new C();ですか?

この質問から:Java継承とC#継承aは、Cのオブジェクトタイプを指しているように見え、cそれらを使用することに違いはないようです。

私はこのコードをテストしました、そしてそれらはすべて印刷しC.mます。

class inherit {

    void x(A a)
    {
        a.m();
    }

    public static void main(String[] args) {
        System.out.println("hello");
        A a = new C();
        C c = new C();
        a.m();
        c.m();

        new inherit().x(a);
        new inherit().x(c);

    }
}
4

4 に答える 4

2

これは、オブジェクトが何に使用されるかによって異なります。

実際に必要なのがA'インターフェイス(つまりA' sタイプ)を持つオブジェクトである場合は、を使用することを強くお勧めしますA a = new C();このようにして、実装ではなくA インターフェースが必要であることを明確にします。後で気が変わったら、他のコードを壊すことなく安全に変更できます。C A a = new Another_Subtype_Of_A();

Aこれは、がインターフェイス(この場合Aはクラス)の場合に特に当てはまります。たとえば、リストが必要な場合は、List list = new ArrayList();がよりも明らかに優れていArrayList list = new ArrayList();ます。これは「実装ではなく、インターフェースへのプログラミング」と呼ばれます。

C特にのインターフェイスを必要とするオブジェクト(特にに存在しないインターフェイス)を作成する場合はA、を選択することをお勧めしますC c = new C();。代わりに書く場合はA a = new C()、遅かれ早かれ、オブジェクトをキャストする必要がありますC(Aには目的のインターフェイスがすべてないため)。なぜわざわざするのでしょうか。

于 2013-02-17T04:34:08.360 に答える
1

変数の実行時タイプについてではありません。Vehicleコンパイル時に、ユーザー入力に基づいて、GarbageTruckまたはである可能性があるオブジェクトがあることだけを知っている場合がありますSportsCar

GarbageTruck t;
...
t = new SportsCar();  //can't do this!

// so we do this:
Vehicle t;
if(user.isFast()) {
   t = new SportsCar();
} else {
   t = new GarbageTruck();
}
于 2013-02-17T04:17:57.497 に答える
1

Java はインターフェイスと実装がすべてです。

インターフェイスは、ユーザーがインターフェイスを実装するクラスと対話する方法を記述するパブリック フィールド (メソッドとプロパティ) のセットです。

実装は、これらのメソッドとプロパティに実際に何かをさせるコードです。実装は のクラスにするimplementsことinterfaceも、他の実装のサブクラスにすることもできます。

クラスをインスタンス化するときは、次のようなコードを記述します。

Interface a = new Implementation();

多くの場合、インターフェイスと実装をすべてまとめてラップします... 別の言い方をすれば、 を定義するとき、インターフェイスを明示的に実装しているかどうかにかかわらず、記述するすべてのメソッドでclassインターフェイスを定義しています。public

したがって、呼び出すことができるメソッドに影響を与えるのはインターフェイスですが、呼び出したときに何が起こるかに影響を与えるのは実装です。

于 2013-02-17T04:23:37.117 に答える
0

最初Aは親クラスで、C子クラスの場合はA a = new A()オブジェクトが作成され、ハンドルAで保持されます。AそうするとC c = new C()、オブジェクトCが作成され、Cハンドルがそれを保持します。しかし、A a = new C()そうすると、オブジェクトCが作成され、Aハンドルがそれを保持します。これは、 のすべてのプロパティCが使用されたことを意味します。のハンドルはAプロパティ (インスタンス) によって使用されますが、 が使用されCます。これがポリモーフィズムです。これで、A ではなく C のオーバーロードされたすべてのメソッドが使用されます。

例として
の使用法 違いは、子クラス用に作成されたメソッドを持つ大規模なプロジェクトを作成するときに発生します メソッドがあると
仮定しますhello
public void hello(C c) { }

将来、A を拡張する別のクラス B があります。その場合、その引数は C 型であるため使用できませんhello。そして、そのようなメソッドを使用する必要がある A の子として多くのクラスがあると想像してください (次に、そのようなメソッドの数)あなたが作成します)。ポリモーフィズムが救いです
A を引数として hello を作成すると、.
public void hello (A x) { }
のすべての子に対して同じメソッドを使用できるようになり ましAた。
A c = new C()
A b = new B()

hello

于 2013-02-17T04:20:11.233 に答える