2017-07-03 14 views
0

ParentChildにキャストできず、ChildからParentまでしかキャストできないと考えました。少なくとも、もしあなたがそうしたのであれば、子供の機能にアクセスすることは許されません。配列の親から奇妙な動作へのキャスト

それから私は、Javaは私が明示的に子供に親をキャストすることができますことを参照してください。

a=(B)a; 

しかし

bArray[0]=a 

または

a.testB(); 

を許可しません。しかし、これはokです。

bArray[1]=(B)a; 

ので、このです:

bArray[1].testB(); 

は誰かがここで何が起こっているか説明していただけます!親クラスにどのように子クラスの関数を与えることができますか?そしてなぜ配列に配置する最初の試みは機能しませんが、2番目の試みは機能しますか?それは同じではありませんか?

class A { 
    public void testA() { 
    } 
} 

class B extends A { 
    public void testB() { 
    } 
} 

public class polymorphicObjects { 
    public static void main(String[] args) { 
     B bArray[] = new B[5];  
     A a = new A(); 
     A ab = new B(); 

     a = (B)a; //didnt think you could do this 
     bArray[0] = a; //but if I can the why doesnt this work? 
     a.testB(); //or this 
     bArray[1] =(B)a; //but this does work 
     bArray[1].testB(); //and so does this!? 
    } 
} 
+3

**なぜこの作品はありませんか?** - あなたは 'a'をタイプAのbeeingとして宣言していますので、それは問題ではありません。 'A a =(B)new A();'変数 'a'は、あなたがそれをどのように定義したかのために、' A'型のままです。とにかく。私は実際には、これは動作しないと確信しているし、それを実行しようとすると、あなたはClassCastExceptionを取得します。コンパイルするだけで動作するということはありません。 –

+0

Haはいクラスキャストの例外です。私はOCJAのために勉強していて、彼らは私に奇妙なものを投げていました。コンパイルするとは思わなかった。ありがとうございます。 – Mason

答えて

0

実行中のbArray[1].testB();は実際に動作しますか?それは少なくともClassCastExceptionをスローするはずです。 testB()メソッドの中にprintステートメントを追加すると、そのステートメントに役立ちます。

したがって、a = (B)a;は、明示的にタイプBにキャストしていますが、実際には何も意味しません。

これは、最初の行のbArray[0] = a;では明示的にキャストされていないため、これは機能しません。そのため、コンパイラは一致しない型を指定していると不満を持ちます。

次の行のbArray[1] = (B)a;では、コンパイラに型がBであることを明示的に伝えているので、実行時にtestB()メソッドの呼び出しが失敗するはずです。

+0

あなたは正しいクラスのキャスト例外です。私はそれをコンパイルするとは思わなかった。私はOCJAのために勉強していましたが、この時点ではEclipseに頼って赤い線で教えていました。コンパイルする前にすべてを捕まえることはできないと思います。ありがとう! – Mason

+0

もしあなたが私の答えを受け入れるならば、私はそれを感謝します:)私は今私の大学のキャリアを通して私が依存してきたコミュニティに戻ってきました。 – SaxyPandaBear

+0

私はしましたが、私はJava Stackoverflowの投票には十分な評判がありません:/イムは主にちょうどlurkerここにハハ。私は十分な担当者がいるときに私は戻って、それを再び投票するでしょう! – Mason

0

Javaでは、キャストは非常に具体的な意味を持ちます(たとえば、C言語とは異なります)。あなたのオブジェクトが実際に持っているクラスと、何らかの式のクラスについてコンパイラが考えるものを区別しなければなりません。

キャスティングは実際のオブジェクトクラスを変更するのではなく、コンパイラが式のクラスについて考えるものだけを変更します。

はのは、あなたのコードを見てみましょう:

new A()はいつもあなたのクラスAのオブジェクトを与える、コンパイラはそれを知っています。

あなたが参照変数aに、コンパイラは変数aは(同様のサブクラスを許可する)クラスAを持っていることを知っている宣言(ないnew A()式)からので、クラスAのものであると宣言したことを保存します。キャスト式(B) aあなたは、aに保存されているオブジェクトについては何も変更するだけであなたは、開発者として、aに格納されているオブジェクトがされていない(タイプBであることを知っているコンパイラに主張していないと

あなたのケースでは、それはAであり、Bではありません)。コンパイラはそれを知るには十分にインテリジェントではないので、式(B) aを有効でクラスBとして扱います。BはAのサブクラスなので、AからBへキャストできます。したがって、クラスAの変数は完全にうまくいくかもしれませんクラスBのオブジェクトを含みます(例えば、A a = new B();は完全にOKです)。実行時に、JVMは実際のオブジェクトクラスをチェックし、サブクラスBから来ていないAであることがわかるとClassCastExceptionを発生させます。

a = (B) a;と同じオブジェクトを同じ変数に戻します。

あなたはこれが原因コンパイラのコンパイルされない程度bArray[0] = a;を尋ねるが、aは、クラスAのオブジェクトが含まれ、そして限り、変数がまだ含まれているとして実行する場合、配列はコンパイルが、ClassCastExceptionがスローされますB. bArray[1] = (B) a;を必要としますコンパイラはbArray内のすべての要素がクラスBであることを知っている、とクラスBは、このメソッドを持っているので、クラスA

そしてbArray[1].testB();の同じオブジェクトがコンパイルされます。 bArrayにクラスBでないオブジェクトを保存しようとすると(コンパイル時にbArray[0] = a;または実行時にbArray[1] = (B) a;になる)、testB()メソッドの呼び出しは安全です。

+0

これは大きな説明です。ありがとう。私はそれについて十分な評判があるときに、この答えに投票して戻ってきます。 – Mason