3

Javaでの継承に頭を悩ませようとしています。Superclass object = new Subclass()これまでのところ、次の方法でオブジェクトを宣言すると、作成された子オブジェクトは親オブジェクトのメソッドに制限されることがわかりました。子の追加メソッドにアクセスしたい場合は、子にキャストする必要があります。しかし、なぜ子クラスでメソッドがまだオーバーライドされているのでしょうか。

これが私の例です

public class Parent {

    public Parent() {       

    }

    public void whoAmI(){       
        System.out.println("I'm a parent");
    }

}
public class Child extends Parent { 

public Child() {        

}

public void whoAmI(){       
    System.out.println("I'm a child");
}

public void childMethode() {
    System.out.println("Foo");

}
}

public class Test {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    List<Parent> list = new ArrayList<>();      

    Child c = new Child();  
    Parent p = new Parent();
    Parent pc = new Child();

    c.whoAmI();
    p.whoAmI();
    pc.whoAmI();

    // Access child methodess
    ((Child) pc).childMethode();

    list.add(c);    
    list.add(p);
    list.add(pc);

    System.out.println(list.size());

}

}

pc.whoAmI()「私は子供です」と印刷します。「私は親です」と表示されないのはなぜですか?

4

5 に答える 5

4

混乱を避けるために、作成するサブクラスオブジェクトには常にすべてのメソッドが含まれていることを理解してください。ダウンキャスティングはノーオペレーションです。まったく同じオブジェクトをサブタイプのインスタンスとして扱うだけです。

当然の結果:ダウンキャストによってオブジェクトの動作を変更することはできません。これから直接、スーパークラスのメソッドではなく、常に同じオーバーライドメソッドにアクセスすることになります。

この種の動作により、同じ宣言されたスーパータイプの代わりに異なる動作を使用できます。これはポリモーフィズムと呼ばれ、Javaプログラミング、および一般的なOOPの主力製品です。それがなければ、そもそもクラス階層を持つことに意味はありません。少なくとも、それははるかに役に立たないでしょう。

于 2012-12-02T15:10:40.423 に答える
1

答えが難しい質問はなぜですか。これは、Java チームがかなり前に行った設計上の決定です。

彼らは、明示的に静的としてマークされていない限り、すべてのメソッドが仮想であると判断しました。一部の言語では逆で (メソッドは仮想宣言されていない限り、デフォルトで静的です)、実際の違いはありません。

重要なことは、静的メソッドと仮想メソッドがどのように機能するかを理解することです。(または、Java で時々呼び出されるように: インスタンスおよびクラス/静的メソッド。)

于 2012-12-02T15:05:05.740 に答える
1

という名前の非表示のメンバーを作成することとして継承を想像できますsuper

Java の各オブジェクト インスタンスには、独自の定数型があります。キャスト中は変更しません。キャストするときは、このオブジェクトがサブタイプであることを確信していることを Java に伝えるだけです。

オーバーライドされたメソッドはオーバーライドされたままです。これが Java のイデオロギーです。C++ の知識があれば、Java のすべての関数は仮想関数であると言えます。

于 2012-12-02T15:05:27.080 に答える
0
class Person{

   public void run(){
       //running

   }

}

class OneLeggedPerson extends Person{
    @Override
    public void run(){
        //cant run have only one leg
   }
}


Person p = new OneLeggedPerson();
p.run();    //cannot as it is actually a one legged person


Hope that makes sense now..
于 2012-12-02T15:13:45.590 に答える
0

あなたが Apple で、iPod を販売しているとしましょう。

iPod の製造方法は、ある工場と別の工場の間、または iPod のモデルの最初のリリースと最後のモデルの間で微妙に異なる場合があります。プロセスが変更されたためです。

あなた、アップル、あなたが作る iPod の種類を知っています。

IPodWithFirstWayOfBuildingIt ipod = new IPodWithFirstWayOfBuildingIt();

また

IPodWithSecondWayOfBuildingIt ipod = new IPodWithSecondWayOfBuildingIt();

しかし、エンド カスタマー (つまり、コードの残りの部分) は、iPod がどのように構築されているかについては気にしません。彼にとって重要なのは、iPod が iPod のように機能し、動作することです (コマーシャル、エンド ユーザー マニュアル、または iPod クラスの javadoc で示されている方法)。彼は店に「最初の作り方の iPod をください」とは言いません。しかし実際のところ、彼は最初の方法か 2 番目の方法で iPod を手に入れました。そして、彼がそれを「iPod」と呼んでいるという事実は、iPod がどのように構築されてきたかを変えるものではありません。

IPod iPod = new IPodWithFirstWayOfBuildingIt();

という言い方です。私は最初の方法で iPod を組み立てますが、どのように組み立てられたかは気にせずに、他の iPod と同じように使用します。

于 2012-12-02T15:17:58.983 に答える