6

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

那里有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);
  }
}

如果这种方法一般来说不是那么好,我怎么能做得更好?

4

3 回答 3

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();
    }
}
于 2013-02-12T22:06:30.613 回答
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 不是一个好主意。

于 2013-02-12T21:50:00.987 回答
1

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

正确的解决方案将取决于该doSomething方法内部到底发生了什么。如果你按照自己的方式去做,那么除了其他事情之外,你还违反了里氏替换原则。我假设您首先因为某些原因决定需要这些层次结构,并且我还假设子类型具有比仅 doSomething 方法更多的行为。在这种情况下,您可以执行的操作如下所示。基本上只有doSomething真正应该做的类型和其他类型做类似no operation. 这样您就可以使用这些对象,而无需知道它们到底是什么类型。

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

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();
}
于 2013-02-12T22:10:21.320 回答