2012-04-19 11 views
0

次のコードについて質問があります(この呼び出しは動的バインディングですか?)。私は約3点を混乱させて感じる。宣言された型と作成された型の関係

まず、変数pqの平均はどうですか? pdはまだPのデータ型かQですか?

第2に、pq.m(pp)メソッドを呼び出すと、結果がQ :: PになるがP :: Qにならない理由は?

最後に、この平均とは((P)qq).m(qq);誰かが私の問題を解決できることを願っています。

次のコードの結果は
P :: Q、Q :: P、Q :: Q、R :: P、Q :: P、Q :: Q、Q :: Q

あろう
class Test { 
    public static void main(String[] args) { 
     P pp = new P();  
     Q qq = new Q(); 
     R rr = new R(); 
     P pq = qq; 
     pp.m(qq);  
     pq.m(pp); 
     pq.m(qq);   
     rr.m(pp); 
     qq.m(pq); 
     qq.m(qq); 
     ((P) qq).m(qq);  
    } 
} 
class P { 
    public void m(P p){System.out.println("P::P"); } 
    public void m(Q p){System.out.println("P::Q"); } 
    public void m(R c){System.out.println("P::R"); } 
} 
class Q extends P { 
    public void m(P p){System.out.println("Q::P"); } 
    public void m(Q p){System.out.println("Q::Q"); } 
    public void m(R c){System.out.println("Q::R"); } 
} 
class R extends Q { 
     public void m(P p){System.out.println("R::P"); } 
     public void m(Q p){System.out.println("R::Q"); } 
    public void m(R c){System.out.println("R::R"); } 
} 
+3

変数 'pd'はありません。したがって、最初の質問に答えることは難しいです... –

+1

しかし、 Javaの継承については、http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.htmlを参照してください。 –

+0

ここでpd ... –

答えて

0

P pq = qq;は、pqが残りの部分でタイプPとして知られていることを意味します。しかし、クリエイターとしては、それが実際にタイプQであることを知っています。つまり、pq.m()を呼び出すと、Qクラスの実装が実際に呼び出されます。

これはメソッドのオーバーライドと呼ばれています。したがって、pq.m(pp)を呼び出すと、実際にはクラスQのメソッドであるので public void m(P p){System.out.println("Q::P");が呼び出されます。

Qにam(P)メソッドがないと、自動的にスーパークラスメソッドが呼び出されます、P.

((P) qq).m(qq);から1をやってと同じです:あなたは本当に継承についてお読みください

P pqq = (P)qq; // pqq is known as P type, but it's instance is still the original Q type 
pqq.m(qq); // Again, since pqq is truly an instance of Q, it calls Q.m(Q) 

。これはここで説明することができるより大きなテーマです。

このすべてが言われていますが、あなたの例はその力をうまく説明していません。クラスQは、その後、余分な方法、public void sayHello();

Q q = new Q(); 
P p = new Q(); 
q.sayHello(); // This would be legal 
p.sayHello(); // This would be illegal because the compiler knows p as a declared instance of P, even though you know it's truly a Q. 
((Q)p).sayHello(); // This would be legal because you told the compiler to look at p as an instance of Q. It's called a cast. 

を持っていた場合でも、例えば、私はこのすべてができます願っています。オブジェクトの向きを必ず読んでください。

0

開始すると、pqで始まり、pdではないと思います。 QはPを延長するので、QもP型である。リンゴは果物だと言っているようなものです。だからあなたはリンゴ(Q)をとり、それが果物だと言います(P)。 pqメソッドを呼び出すと、pqは依然としてQオブジェクトなので、Qクラスのメソッドが呼び出されます。あなたが((P) qq).m(qq);を行う際に最後の部分で は、以下を実行することと同じです。

P p = (P) qq; 
q.m(qq); 

ので、コードはまだQクラス、印刷「Q :: Q」からメソッドを呼び出します、上記の言ったように

0

ダイナミックバインド、したがって多型は、メソッドコール(o.m(x) - oのみ)のドットの左側のオブジェクトに対してのみ機能します。引数の型はコンパイル時に静的に解決されます。ここでのポイントは、そのクラスA、Object.equals(Object)は変更しないで、代わりにちょうど別のオーバーロードされたメソッドAを追加し

class A { 
    public boolean equals(A other) { 
    System.out.println("A.equals called"); return true; 
    } 
} 

A a1 = new A(), a2 = new A(); 
Object o = a1; 
o.equals(a1); // doesn't print anything 
a1.equals(o); // doesn't print anything 
a1.equals(a2); // prints "A.equals called" 

:もっとよく知られている状況を取ります引数が宣言された型である場合にのみ呼び出されます。

+0

申し訳ありません...私はダウンしていません。私はあなたの説明が非常に混乱していると感じました。なぜなら、あなたがC++ではなくJavaを記述しているように思えたからです。あなたが追加した最後の段落はあなたの答えを改善します。 – stevevls

関連する問題