2011-07-10 12 views
1

Java以外のバックグラウンドからScalaに移行すると、これを含むさまざまな困難がもたらされました。Scala:ダウンキャスティングでjava.lang.ClassCastExceptionがスローされる

scala> class A 
defined class A 

scala> class B extends A  
defined class B 

scala> val a = new A 
a: A = [email protected] 

scala> val b = new B 
b: B = [email protected] 

scala> a.asInstanceOf[B] 
java.lang.ClassCastException: A cannot be cast to B 
... 

scala> b.asInstanceOf[A] 
res1: A = [email protected] 

私はClassCastExceptionが発生があるため、実行時にスローされることを理解し、aはBのように見えるしていませんが、実際には、それは(私の知る限り理解して)です。何が起きてる?回避策はありますか?ありがとう。

編集:aBにキャストできないことをJVMがどのように理解していますか? a.getClassBの間でいくらか浅い比較を実行しますか?

ps。プライベート変数をライブラリクラスに追加しようとしていて、ライブラリに定義されているクラスを引数として受け入れるクラスメソッドの1つをオーバーライドしようとしています(クラスをクラスに追加しようとしています)。 Bは、それがダウンした階層だA.

+0

ライブラリクラスを拡張して、拡張クラスにプライベート変数を追加し、代わりにそのクラスを使用できますか?関数とメソッドは、Scala fyiで互いにオーバーライドします。 – mythicalprogrammer

+0

あなたが言ったように、私は変数を拡張して追加します。しかし、私がオーバーライドする必要があるメソッドを持つライブラリのファクトリクラスは、古いクラスだけを引数として受け入れます。 – parsa

+0

@parsaこれと比べて: 'val m:A = new B(); m.asInstanceOf [B] '。うまくいけばそれはいくらか意味をなさないでしょう。 –

答えて

6

よりも特異的であるため

+0

あなたはそうです、Javaを知らない以上です。 – parsa

4

あなたは、唯一の他の方法で回避、BAをキャスト傾けます。クラスAはスーパークラスであり、Bはそのクラスから拡張されているため、より具体的です。あなたは一般化で階層を上げることはできません。これは設計上の選択で、subtypingに関連しています。

階層が上がる言語はありますか?あなたがそのような言語があることを暗示しているように思われるからです。

+0

はいAによって定義された車であり、BはBMWですが、追加のフィールドや方法はありません。 (あるいは悪いソフトウェア設計を防ぐためだけにあるのですか?) – parsa

+2

@parsaキャストは*実行時*操作です。 *オブジェクト*のタイプはAです - この場合はBではありません。したがって、* kaboom *! Bの*オブジェクト*がAの*変数*に隠れていれば、大丈夫でしょう。それは哺乳動物(A)を豚(B)に投げかけようとするようなものです。豚はOinkすることができますが、哺乳動物の方が一般的です:Oinkはできません:(しかし、豚は哺乳動物のように扱われれば完璧にうまくいきます。 –

関連する問題