假设我有以下课程:
public interface X {
...
}
public class A implements X {
...
}
public class B implements X {
...
}
现在假设我有一个方法,它采用X类型的对象,并且必须以不同方式处理X的每个实现。天真的方法是:
public void doSomething(X x) {
if(x instanceof A)
doSomethingA((A) x);
else if(x instanceof B)
doSomethingB((B) x);
}
...但这似乎特别丑陋而且不是多态的。一般来说处理这种情况的干净方法是什么?
编辑:当然,如果我可以将doSomething()的实现推送到A类和B类,那会很容易,但在那些没有意义的情况下呢?即doSomething()是在C类上定义的,并且实现高度依赖于C的内部状态。
答案 0 :(得分:6)
很简单:
public interface X {
int doSomething();
}
public class A implements X {
public int doSomething() {
// implementation in A
}
}
public class B implements X {
public int doSomething() {
// implementation in B
}
}
UPDATE:好的,好像在这里我们在C中有一些算法,它依赖于C的状态以及A / B的差异。然后我会尝试拆分该算法,以便C类只有A和B的通用实现,并且A / B相关的部分应该作为在C中调用的相同方法的特定实现转到适当的类。如果可能的话,C的状态可以部分传递给A和B的doSomething
答案 1 :(得分:4)
您应该将doSomethingA
的实施推送到课程A
和doSomethingB
推送到classB
,在界面doSomething
中定义X
致电x.doSomething()
(double-dispatch行)。
考虑到有关X
类型为A
或B
的处理依赖关系的问题的最新修改,当然不应使用instanceof
运算符,因为它建立了对底层实现类的硬依赖性,当传递给X x
的{{1}}是一个装饰实例时代码会失败。
AFAIK,C.doSomething()
的实施将归结为您必须使用C.doSomething()
或A
中的信息,并且应该抽象此处运行的步骤在B
和A
中的方法,在接口B
中声明。这将确保X
的任何新实现也实现X
依赖的此方法,从而使代码更易于维护。 HTH。
答案 2 :(得分:2)
执行此操作的正确方法是visitor pattern
答案 3 :(得分:0)
首先,我会实现一个接口而不是扩展:)并且我的第一次尝试将是这样的
class Parent {
public Parent() {
}
}
class Child extends Parent {
public Child() {
super();
}
}
public class MainClass {
public static void main(String[] a) {
Child child = new Child();
if (child instanceof Parent) {
System.out.println("true");
}
}
}
答案 4 :(得分:0)
public interface X {
doSomeThing();
}
public class A implement X {
doSomeThing(){}
}
public class B implement X {
doSomeThing() {}
}
现在你可以使用
X a = new A();
a.doSomeThing();
答案 5 :(得分:0)
你可以在界面X中移动做某事()吗?然后只需调用x.do something()而无需强制转换或使用。的实例。
答案 6 :(得分:0)
这更像是一个设计问题。 如果doSomething()的A和B实现严重依赖于C对象状态,则可以将其作为参数传递:x.doSomething(C c)
在界面X中创建doSomething():
public interface X {
doSomething(C c);
}
public class A extends X {
doSomething(C c) {
...
}
}
public class B extends X {
doSomething(C c) {
...
}
}
然后,您的初始方法变为:
public void doSomething(X x) {
x.doSomething(C c);
}