2012-11-22 62 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解决方案将需要它。无论如何,超类不应该知道,有任何子类。 –