2013-02-12 124 views
5

我有一个从基类扩展的对象列表。现在我只想对列表中的一个类实例应用特定的操作。instanceof是一种好的做法吗?

是否使用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); 
    } 
} 

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

+6

使用多态性;这就是它存在的原因。 – 2013-02-12 21:48:42

+0

- 而不是doSomething(base) - 你应该实现一些base.doSomething(),它在foo.doSomething()中被覆盖。 Google多态java或 - 覆盖方法java。 – 2013-02-12 21:50:08

+3

我喜欢这个特定的答案:http://www.javapractices.com/topic/TopicAction.do?Id = 31。我意识到C++和Java是不同的,但是**“如果对象是T1类型的话,任何时候你发现自己在写代码的形式”,然后做一些事情,但是如果它是T2类型的,那么做一些其他的事情,“拍拍自己。 * – thang 2013-02-12 21:59:43

回答

3

实际上似乎没有任何理由使用此处的实例。让基类将行为默认为无所事事,并在需要时扩展类时重写它可能是有意义的。这样你只需要覆盖它(如果需要的话,我将它作为一个抽象类来跟随这个例子不需要的问题)。 例如:

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(); 
    } 
} 
+0

这是一个非常好的想法,因为我可以省略实现类的应用程序,该应用程序不会对该方法调用做任何事情。 – membersound 2013-02-12 22:33:42

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不是一个好主意。

+3

你为什么现在要检查instanceof ..你不需要 – smk 2013-02-12 21:51:55

+2

错误的语法,它应该是“base instanceof Bar” – shuangwhywhy 2013-02-12 21:55:06

+0

为什么你使用instanceof的时候应该不是个好主意? – membersound 2013-02-12 21:58:45

1

的是这里没有一个好的做法的实例。

正确的解决方案将取决于doSomething方法内的确切内容。 如果你这样做,除了其他的事情,你违反Liskov Substitution Principle。我假设你决定首先需要这些层次结构,并且我还假定子类型比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(); 
}