2011-09-10 12 views
4

G'day people、ナイーブ継承問題 - Java

このような素朴な質問をして困っています。しかし、私はBがAを拡張

enter image description here

、私はこのような継承構造を持つ 、一つのことを理解することはできません、私が書いているコードは

クラスA

public class A{ 
    private int pos = 0; 
    public A(){ 
     this.pos = 12; 
    } 
    public int getPos(){ 
     return this.pos; 
    } 
} 
、以下の通りであります

クラスB

public class B extends A{ 
    int spec = 15; 
    public B(){ 
     super(); 
    } 
    public int getSpec(){ 
     return this.spec; 
    } 
} 

私はもう一つのクラスをテストしています。それで私は私の質問に繋がります。

クラスTest

import java.util.*; 
public class Test{ 
    public static void main(String[] args){ 
     B a = new B(); 
     ArrayList<A> c = new ArrayList<A>(); 
     c.add(a); 
     System.out.println(c.get(0).getPos()); 
     System.out.println(c.get(0).getSpec()); 
    } 
} 

質問:今、私はBのインスタンスを作成しています、私は私の親クラスのメソッドgetPos()とBの独自の方法getSpec()にアクセスできることを意味します。しかし、タイプAのArrayListを作成した場合(... BもタイプAなので...)、自分のメソッドにアクセスする能力が失われてしまいます。私は間違って何をしていますか? ArrayList実装はBを内部的にAにキャストしていますか?


注:継承の私の基本的な理解は、彼らが保護されていない以外 子供のメソッドにアクセスすることができ、親です。しかし、子は親クラスのメソッド にアクセスできます。

答えて

3

@Matt Ball@Hovercraft Full Of Eelsでの回答に加えて、あなたはすることを避けることができますが、明示的にスーパーサブクラス抽象などの方法で実装されているメソッドを宣言することによってをキャスト。

public abstract class A{ 
    . 
    . 
    public abstract int getSpec(); 
} 

編集 -

@Kublai Khan

により述べたように、抽象クラススーパーを行い、その後に必要です。

+1

+1です。そして、 'A'は今抽象クラスにする必要があることを忘れないでください。 –

+0

@Kublai Khan、+1大きなポイント!ありがとうございました。 :D – mre

4

キャスティングはありません。あなたがやっていることは、この違いはありません:

A bAsA = new B(): 

バサによって参照されるオブジェクトが本当にBのオブジェクトですが、それは変数によって保持され、明示的にキャストしない限り、これだけの方法が利用可能です( B変数として)。

ArrayListはAのArrayListであるため、ArrayListの各項目はA変数として扱われ、Aメソッドのみが使用できます。

4

ArrayList実装はBを内部的にAにキャストしていますか?

いいえ「内部キャスト」はありません。 あなたはプログラマであり、コンパイラにAのリストであることを伝えました。

あなたははあなたがAのリスト」として読むことができるList<A>、としてListを宣言しています。 BはすべてAなので、にはBを追加できます。検索では、しかし、あなただけAなく、戻って取得することを保証しているB —それはList<A>だから、—を覚えているので、コンパイラ扱いAとしてリストから出てくるすべて、たとえ(実行時に)それはBのインスタンスです。

+0

Mattさん、ありがとうございました。 Btw 1つのArrayListに子のコレクションを入れたいのですが? ArrayListのように何かできますか ...;毎回キャストしますか?または何か回避策がありますか? – doNotCheckMyBlog

+0

すばらしい答え! 1 + –

+2

@Skeet:重いキャスティングはプログラムに悪い匂いを与え、プログラムデザインを注意深く見なければならないことを示唆しています。なぜなら、それが壊れていて、はるかにオブジェクト指向の方法で改善できる可能性が高いからです。 –