在java中处理这个问题的首选方法是什么

时间:2012-10-03 10:50:06

标签: java oop polymorphism

假设我有以下课程:

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

7 个答案:

答案 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的实施推送到课程AdoSomethingB推送到classB,在界面doSomething中定义X致电x.doSomething()double-dispatch行)。

考虑到有关X类型为AB的处理依赖关系的问题的最新修改,当然不应使用instanceof运算符,因为它建立了对底层实现类的硬依赖性,当传递给X x的{​​{1}}是一个装饰实例时代码会失败。

AFAIK,C.doSomething()的实施将归结为您必须使用C.doSomething()A中的信息,并且应该抽象此处运行的步骤在BA中的方法,在接口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);
}