2

假设我有以下课程:

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 的内部状态。

4

7 回答 7

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
  }  

}

更新:好的,看来我们在 C 中有一些算法,它取决于 C 的状态以及 A/B 差异。然后我会尝试拆分该算法,以便 C 类只有 A 和 B 的通用实现,并且依赖于 A-/B 的部分应该转到适当的类作为在 C 中调用的同一方法的特定实现. 如果可能,C 的状态可以部分传递给 A 和 B 的 doSomething

于 2012-10-03T10:54:04.053 回答
4

您应该推送doSomethingAto classAdoSomethingBto的实现,在接口classB中定义并调用(在double-dispatch行中的内容)。doSomethingXx.doSomething()

考虑到有关处理对X类型Aor的依赖性的问题的最新编辑Binstanceof肯定不应该使用运算符,因为它建立了对底层实现类的硬依赖,并且当X x传递给C.doSomething()修饰时,代码将惨遭失败实例。

AFAIK, 的实现C.doSomething()将归结为您必须使用来自Aor的信息,B并且在该点运行的步骤应该抽象为 and 中的方法AB在 interface 中声明X。这将确保任何新的实现X也实现这个C依赖的方法,从而使代码更易于维护。HTH。

于 2012-10-03T10:53:54.320 回答
2

正确的方法是访问者模式

于 2012-10-03T10:54:19.633 回答
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");
        }

      }

    }
于 2012-10-03T10:55:15.900 回答
0
 public interface X {
     doSomeThing();
    }

public class A implement X {
  doSomeThing(){}
}

public class B implement X {
   doSomeThing() {}
}

现在你可以使用

  X a = new A();
  a.doSomeThing();
于 2012-10-03T10:55:40.077 回答
0

你能把 do something() 移到接口 X 中吗?然后只需调用 x.do something() 而无需强制转换或使用实例。

于 2012-10-03T10:55:45.260 回答
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);
}
于 2012-10-03T11:00:25.403 回答