2011-07-10 31 views
1

從非Java背景到Scala帶來了包括這個在內的各種困難。Scala:downcasting throws 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,而事實上,它是(據我所知)。這裏發生了什麼?任何解決方法?謝謝。

編輯:JVM如何理解a不能被鑄造到B?它是否執行a.getClassB之間的淺層比較?

ps。我試圖給庫類添加一個私有變量,並重寫一個接受庫中定義的類作爲參數的類方法(我試圖添加該字段的類)。

+0

您可以擴展庫類並在擴展類中添加私有變量並使用該類來代替?函數和方法在Scala fyi中互相重疊。 – mythicalprogrammer

+0

我按照你說的去做,我擴展並添加變量。但是,我需要重寫的方法庫中的工廠類只接受舊類作爲參數。 – parsa

+0

@parsa與此比較:'val m:A = new B(); m.asInstanceOf [B]'。希望這會有所幫助。 – 2011-07-10 07:38:55

回答

6

更具體的就這麼下降一個層次。 A類是一個超類,B從它延伸出來,因此它更具體。在泛化過程中,你無法上升到層次結構。這是一個設計選擇,涉及到subtyping

有沒有什麼語言可以上升到層次結構?因爲你似乎暗示有這樣的語言。

+0

你是對的,它不僅僅是不瞭解Java。 – parsa

4

你不能投AB,只有周圍的其他方法,因爲B比A.

+0

是的定義A是一輛汽車,B是寶馬,但沒有額外的領域或方法,什麼是禁止被視爲B? (或者它僅僅是爲了防止不好的軟件設計?) – parsa

+2

@parsa演員陣營是一個*運行時*操作。 * object *的類型是A - 在這種情況下不是B - 因此,* kaboom *!如果B類型的* object *隱藏在A的*變量*中,那麼它會沒事的。這就像試圖將哺乳動物(A)投向豬(B)。豬可以嗅覺,但是哺乳動物的對象更普遍:它不能Oink :(不過,如果它像哺乳動物一樣被對待,豬是完美的) – 2011-07-10 07:33:00