2013-02-12 3 views
5

У меня есть список объектов, которые простираются от базового класса. Теперь я хочу применить определенную операцию только к одному экземпляру классов в списке.Является примером хорошей практики?

Является ли использование 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

Использовать полиморфизм; поэтому он существует. –

+0

точно - вместо doSomething (base) - вы должны реализовать некоторый base.doSomething(), который переопределяется в foo.doSomething(). Google полиморфизм java - или - переопределить метод java. –

+3

Мне нравится этот конкретный ответ: http://www.javapractices.com/topic/TopicAction.do?Id=31. Я понимаю, что C++ и Java разные, но ** «Каждый раз, когда вы находите себе код формы», если объект имеет тип T1, а затем что-то делать, но если он имеет тип T2, тогда сделайте что-нибудь еще », * – thang

ответ

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

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

Почему вы сейчас проверяете экземпляр .. У вас нет – smk

+2

Неправильный синтаксис, он должен быть «базовым экземпляром бара» – shuangwhywhy

+0

Почему вы используете экземпляр if, когда предполагается, что это не очень хорошая идея? – membersound

1

экземпляра не является хорошей практикой здесь.

Правильное решение будет зависеть от того, что именно происходит внутри этого метода doSomething. Если вы делаете это по-своему, то, помимо других вещей, вы нарушаете Liskov Substitution Principle. Я предполагаю, что вы решили, что вам нужна эта иерархия в первую очередь из-за чего-то, и я также предполагаю, что подтипы имеют некоторое поведение, а не только метод 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(); 
} 
Смежные вопросы