Java 使用只能在运行时获得的静态类型
假设我的情况如下: 类Java 使用只能在运行时获得的静态类型,java,inheritance,instanceof,dynamic-cast,static-typing,Java,Inheritance,Instanceof,Dynamic Cast,Static Typing,假设我的情况如下: 类X具有类型为s的字段s S被两个类A和B扩展,这两个类都实现了一些我们都知道应该在S中实现的相同方法/字段,但不幸的是,情况并非如此 现在我想做这样的事情: "A or B" downcast_field; if(s instanceof A) downcast_field = (A)s; else if (s instanceof B) downcast_field = (B)s; //do something common for the two c
X
具有类型为s
的字段s
S
被两个类A
和B
扩展,这两个类都实现了一些我们都知道应该在S
中实现的相同方法/字段,但不幸的是,情况并非如此
现在我想做这样的事情:
"A or B" downcast_field;
if(s instanceof A)
downcast_field = (A)s;
else if (s instanceof B)
downcast_field = (B)s;
//do something common for the two cases but that need methods implemented both in A and B
问题是预先有一个静态类型(在IFs
中),允许我调用这样的方法
我想,由于糟糕的设计,这实际上是不可能的,我必须编写两次相同的代码,这很难看,但也许有一个解决方案我现在没有看到。如果您可以更改
a
和B
,那么您可以将相同的接口添加到两者。这将允许您将此类型赋予downcast\u字段
并调用方法
如果无法更改A
和B
,则有两个选项:
- 您可以编写
和A2
。将B2
和A
中的代码复制到新类型中。这允许您修改代码(除非您无法控制这些类型的创建)。或者,您现在还可以创建扩展B
的S
,并将公共代码放在其中,然后从中扩展S2
/A2
B2
- 创建一个接口,然后创建两个实现,将调用委托给实际类型
在这个解决方案中,您可以
您可以使两个包装器扩展相同的类型,并将公共代码移到那里Wrapper downcast_field; if(s instanceof A) downcast_field = new AWrapper( (A)s ); else if (s instanceof B) downcast_field = new BWrapper( (B)s ); downcast_field.foo();
- 据我所知,您的情况如下
public class S {
}
public class A extends S {
public void doSomething() {
System.out.println("A is doing something ...");
}
}
public class B extends S {
public void doSomething() {
System.out.println("B is doing something ...");
}
}
实际上我觉得这个设计很糟糕。如果你有机会
清理干净,你应该这样做。如果这不是一个选项,请执行以下操作
解决方法是可能的。。。引入一个声明公共API的接口
并使用此接口包装您的实例
public interface WrapperInterface {
void doSomething();
}
那么你可以这样用这个
public class Main {
public static void main(String[] args) {
WrapperInterface a=wrap(new A());
WrapperInterface b=wrap(new B());
a.doSomething();
b.doSomething();
}
private static WrapperInterface wrap(final S s) {
WrapperInterface downcast_field=null;
if (s instanceof A)
downcast_field = new WrapperInterface() {
@Override
public void doSomething() {
((A) s).doSomething();
}
};
else if (s instanceof B) {
downcast_field = new WrapperInterface() {
@Override
public void doSomething() {
((B) s).doSomething();
}
};
}
return downcast_field;
}
}
你能给
A
和B
添加一个界面吗?这个设计太糟糕了!你需要改变it@pratik如果可能的话,我早就这么做了!不幸的是,它必须一直保持这样的状态,您在哪个类中使用上述代码?理想情况下,A或B可以用S本身在类X中表示,字段的类型为S。我喜欢使用委托包装类,除了它添加了另外三个具有A
和B
特定知识的类,只是为了这个目的,这有点草率。考虑到这个场景,我认为这几乎是最好的解决方案(除了Java8中的东西,但很可能您没有使用它…)是的,您可以使用方法引用、闭包或反射。引用应该很快,闭包应该很好,反射会很慢。用中产阶级扩展S是我最初的想法。总的来说,我认为在任何情况下都不可能有任何优雅的解决方案。谢谢你给我这么多的可能性@Shotgunnija的机会是正确的,没有java8:-/