这是一个好的做法吗?

时间:2013-02-12 21:47:38

标签: java oop enums

我有一个从基类扩展的对象列表。现在我想仅对列表中的一个类实例应用特定操作。

使用instanceof是一种很好的做法吗?或者我应该通过自定义enum来区分对象?

abstract class Base;
class Foo extends Base;
class Bar extends Base;

List<Base> bases;

for (Base base : bases) {
  if (base instanceof Bar.class) {
     //execute my custom operation on the base object
     doSomething((Bar) base);
  }
}

如果这种方法一般不太好,我怎么能做得更好?

3 个答案:

答案 0 :(得分:3)

似乎没有任何理由使用此处的实例。让基类默认行为无效并在需要时在扩展类中覆盖它可能是有意义的。这样你只需要在需要时覆盖它(我on.y把它留作抽象类来跟随这个例子不需要的问题)。 例如:

abstract class Base{
    public void doSomething(){}
}

public class B0 extends Base{
    @Override
    public void doSomething(){//actually do something}
} 

public class B1 extends Base{}

使用它的一个例子可能是:

public class SomeOtherClass{
    public void something(List<Base> bases){
         for(Base base:bases)
             base.doSomething();
    }
}

答案 1 :(得分:2)

abstract class Base;//abstract function doSomething()
class Foo extends Base;//implements doSomething()
class Bar extends Base;//dito

List<Base> bases;

for (Base base : bases) {
     base.doSomething();
}

回答你的问题:使用instanceof不是一个好主意。

答案 2 :(得分:1)

这里的实例不是一个好习惯。

正确的解决方案将取决于doSomething方法内部究竟发生了什么。 如果你按照自己的方式行事,那么除了其他事情,你违反了Liskov Substitution Principle。我假设您决定首先需要这些层次结构,因为有些东西我也认为子类型比只有doSomething方法有更多的行为。在这种情况下,您可以执行的操作如下所示。基本上只有doSomething实际执行此类型的类型,而其他类型的类型执行no operation之类的操作。通过这种方式,您可以使用这些对象,而无需知道它们的实际类型。

您还应该问自己,您是否真的需要Base类是抽象类。也许你需要的只是一个界面。可能有更好的方法,但基于我所拥有的信息以及我所假设的信息,这似乎没有问题。

public abstract class Base
{
    public abstract void doSomething();

    public void someOtherMethod()
    {
        // which does stuff
    }
}

public class SubTypeWhichCanDoSomething extends Base
{
    @Override
    public void doSomething()
    {
        // actually implement method and DO something
    }
}

public class DoesNothing extends Base
{
    @Override
    public void doSomething()
    {
        // does nothing
        return;
    }
}

// then your code looks like these
for(Base base : bases)
{
    base.doSomething();
}