2012-11-22 63 views
0

說我有一個基類:鑄造基地型與Java

abstract class TheBase {} 

class Foo extends TheBase {} 
class Bar extends TheBase {} 

我想「投」基對象插入此類型:

TheBase obj = getFromSomewhere(); 

Foo foo = obj.asA(Foo.class); 

Bar bar = obj.asA(Bar.class); 

asA將拋出一個例外,我有定義爲:CustomCannotCastException()

這可能嗎?

+0

起初,不要在TheBase類中進行強制轉換。讓來電者決定,你得到的是哪個類 –

+0

@JordiLaforge:但是調用者正在決定她想要哪個類(通過參數)。 – Thilo

+2

爲什麼重新發明標準的鑄造機制?爲什麼不做'Foo foo =(Foo)obj;'?爲什麼你自己的'CustomCannotCastException'而不是使用標準的'ClassCastException'? – Jesper

回答

9

你需要這樣的東西嗎?

public class TheBase { 
    public <T> T asA(Class<T> claxx) { 
     if (claxx.isInstance(this)) { 
      return claxx.cast(this); 
     } else { 
      throw new CustomCannotCastException(); 
     } 
    } 
} 
+0

我依稀記得這種模式(「自鑄類」)有一個名字。你能幫我嗎? –

+0

恐怕我不知道這是否是一種命名模式。 – Flavio

+0

也許你的意思是「Downcasting」,它是一種代碼:http://codebetter.com/jeremymiller/2006/12/26/downcasting-is-a-code-smell/ –

1
if(obj instanceof Foo) 
{ 
    Foo foo = (Foo)obj; 
} 

if(obj instanceof Bar) 
{ 
    Bar bar = (Bar)obj; 
} 
+0

我需要'asA'方法拋出自己的自定義異常,這就是爲什麼我不能像這樣做直接投射 – xybrek

+0

好吧,它的可能,等待我的答案更新 –

+0

弗拉維奧已經回答了。 +1。 –

1

我不會把asA-Method放在TheBase-Class中。 我會prever一個代碼,它看起來像這樣:

TheBase obj = getFromSomewhere(); 
Foo foo = Foo.getInstance(obj); 
Bar bar = Bar.getInstance(obj); 

//例爲FOO

public Foo getInstance(TheBase aBaseSomething) { 
     if (aBaseSomething instanceof Foo) { 
      return (Foo)aBaseSomething; 
     } else { 
      throw new CustomCannotCastException(); 
     } 
    } 

所以需要的子類可以決定,做什麼,並且超並不需要知道有子類。

+0

@ Flavio的解決方案不需要所有類的列表。 – Thilo

+0

但@PC解決方案將需要它。無論如何,超類不應該知道,有任何子類。 –