2009-08-30 25 views
1
public class A 
{ } 

public class B extends A 
{ 
    public void add() 
    { 
    System.out.println("add in B"); 
    } 
} 

ここで、次のようにaddを呼び出すと、エラーが返されます。 A a1 = new B; a1.add();親クラスの子メソッドを子クラスのオブジェクトを参照している親クラスの参照で呼び出す必要があるのはなぜですか?

しかし、クラスAにadd()メソッドを追加して同様の方法で呼び出すと、子クラスのadd()メソッドが呼び出されます。

すなわち

public class A 
{ 
    public void add() 
    { 
    System.out.println("add in A"); 
    } 
} 

public class B extends A 
{ 
    public void add() 
    { 
    System.out.println("add in B"); 
    } 
} 

コール:

A a1 = new B; 
a1.add(); 

出力:

add in B

なぜそれはそうでしょうか?

+0

これはポリモーフィズムのケースです –

答えて

1

Javaは、コンパイル時に、a1が実行時にBのインスタンスを参照することがわからないためです。宣言された型だけを知っているので、宣言された型で動作する呼び出しのみが許可されます。

2

a1.add()のメソッド呼び出しで、コンパイラはメソッドが存在するかどうかをチェックします。しかし、それはa1がそのメソッドを持たないクラスAのオブジェクトへの参照であることだけを知っています。コンパイルに失敗します。

この簡単な例では、おそらくコンパイラが正しい型を差し引くのは簡単でしょう。しかし、もっと一般的なケースではそうではありません。したがって、この種のロジックは仕様の一部ではありません。

+0

実際にメソッドを呼び出すとき、JVMはランタイムを解決します。このメソッドは、変数に保持されている値の実行時の型に基づいて呼び出します。あなたの場合、変数a1の実際の値はBなので、クラスBで宣言されたメソッドaddが呼び出されます。 – Nikem

0

Javaコンパイラが参照a1を参照すると、利用可能なメソッドがわかります。あなたの最初の例では、クラスAはそのAPIにadd()を持っていません。この場合、a1Bのキャストを次のように実行することは合法です。

((B)a1).add();

とコンパイラは不平を言っていません。

0

宣言された型Aのオブジェクトに対してメソッドを呼び出すが、AのサブクラスBでのみメソッドを実装したい。この場合、通常はAをabstract classとし、Aで抽象メソッドを宣言する。

0

良い答え...これについても疑問がありましたが、今私は明確です:) もう一つのこと..あなたは抽象メソッドを宣言するのに苦労する必要はありません。あなたの親クラスと同じ名前と署名を持つメソッド "voila"はすべてのコンパイルエラーはなくなりました;)

あなたの場合は、このようなvoid add(){}メソッドを追加することができますave任意の問題

関連する問題