我有一个超类Foo
和许多子类Bar1
.. BarN
,它们扩展了超类。
public Foo { .. }
public Bar extends Foo { .. }
public Bar2 extends Foo { .. }
.......
public BarN extends Foo { .. }
我试图在运行时确定子类的类型,然后通过if,else-if,else语句转到下一个操作但是我决定尝试新的东西,看看我是否可以减少代码行数以便我提出下面的代码,没有编译错误。但是它没有涵盖所有儿童班的情况。
private void doSomething(Foo foo) {
boolean trigger = false;
if ( (trigger = foo instanceof Bar ? true : false)
|| (trigger = foo instanceof Bar2 ? false : true) ) {
if (trigger == true) { // do Bar thing }
else { // do Bar2 thing }
}
}
所以我对自己说,而不是使用boolean
类型作为触发变量,让我使用int类型作为同一个变量。例如1表示Bar
,2表示Bar2
,3表示Bar3
等等。所以我重新设计了我的代码然后我收到编译错误,说“运算符||未定义为参数type(s)int,int“in first if statement。我不知道如何解释这条消息。
private void doSomething(Foo foo) {
int trigger = 0;
if ( (trigger = foo instanceof Bar ? 1 : 0)
|| (trigger = foo instanceof Bar2 ? 2 : 0) ) {
if (trigger == 1) { // do Bar thing }
else if (trigger == 2) { // do Bar2 thing }
}
}
答案 0 :(得分:6)
而不是告诉你如何让它按照你想要的方式工作(为了它的价值,@Sebastian's answer is a clean way of doing what you've been trying to do),这是一种更快,更清晰的方法。
在这里使用面向对象的优势,而不是通过可能的慢instanceof
检查来浪费所有这些复杂性。这将允许您保持Foo
的每个实现的行为以单独处理每个类,并且行为在单独的方法中,因此不会让人感到困惑。它是无分支的,这意味着您不必进行任何if
个调用,这些调用可能很慢而且很麻烦,正如您自己注意到的那样。代码更容易更快地遵循和。
以下是它的工作原理(这是样板文件,你不在这里做任何逻辑):
public interface Foo {
void accept(FooVisitor visitor);
}
public class Bar implements Foo {
void accept(FooVisitor visitor) {
visitor.visit(this);
}
}
public class Bar2 implements Foo {
void accept(FooVisitor visitor) {
visitor.visit(this);
}
}
然后,在你一直在写的课上,做(这就是行为所在的地方):
private void doSomething(Foo foo) {
foo.accept(this);
}
private void visit(Bar bar) {
// do Bar thing
}
private void visit(Bar2 bar2) {
// Do Bar2 thing
}
答案 1 :(得分:2)
您可能需要以下内容:
int trigger = (foo instanceof Bar) ? 1 :
(foo instanceof Bar2) ? 2 :
(foo instanceof Bar3) ? 3 :
0; // in case it's not an instance of any