2013-02-12 13 views
5

Mam listę obiektów, które rozciągają się od klasy bazowej. Teraz chcę zastosować konkretną operację tylko na jednej instancji klas na liście.Czy dobrym przykładem jest instancja?

Czy jest to dobra praktyka z zakresu instanceof? Czy raczej powinienem odróżnić obiekty np. Od niestandardowego 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); 
    } 
} 

Jeśli to podejście nie jest ogólnie przyjemne, jak mogę to zrobić lepiej?

+6

Użyj polimorfizmu; właśnie dlatego istnieje. –

+0

exact - zamiast doSomething (base) - powinieneś zaimplementować metodę base.doSomething(), która jest nadpisana w foo.doSomething(). Google polimorfizm java - lub - przesłonić metodę java. –

+3

Podoba mi się ta konkretna odpowiedź: http://www.javapractices.com/topic/TopicAction.do?Id=31. Zdaję sobie sprawę, że C++ i Java są różne, ale ** "Za każdym razem, gdy piszesz kod formularza", jeśli obiekt jest typu T1, to zrób coś, ale jeśli jest to typ T2, to zrób coś innego, "uderz się." * – thang

Odpowiedz

3

Tak naprawdę nie ma powodu, aby używać przykładu tutaj. Może być sensowne, aby klasa podstawowa była domyślnie zachowana, tak aby nic nie robić i nadpisywać ją w rozszerzaniu klas, gdy zajdzie taka potrzeba. W ten sposób nadpisujesz go tylko w razie potrzeby (opuściłem to jako abstrakcyjną klasę, której należy przestrzegać z pytaniem, które nie jest potrzebne w tym przykładzie). Na przykład:

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

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

public class B1 extends Base{} 

Przykładem zastosowania może to być coś takiego:

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

To bardzo dobry pomysł, ponieważ wtedy mogę pominąć implementację na klasach, które powinny po prostu nie robić nic w tej metodzie. – 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(); 
} 

Aby odpowiedzieć na pytanie: nie jest dobrym pomysłem użycie instanceof.

+3

Dlaczego teraz sprawdzasz instanceof ... Nie musisz – smk

+2

Niewłaściwa składnia, powinna to być "' podstawowa instancja paska '" – shuangwhywhy

+0

Dlaczego używasz instanceof, gdy nie jest to dobry pomysł? – membersound

1

wystąpienie nie jest dobrą praktyką tutaj.

Prawidłowe rozwiązanie zależy od tego, co dokładnie dzieje się w metodzie doSomething. Jeśli zrobisz to na swój sposób, to poza tym naruszysz Liskov Substitution Principle. Zakładam, że zdecydowałeś, że potrzebujesz tej hierarchii przede wszystkim z powodu czegoś, a także założę, że podtypy mają nieco więcej zachowań niż tylko metodę Zrób coś. W tym przypadku, co możesz zrobić, pokazano poniżej. Zasadniczo tylko typy, które powinny to zrobić, a reszta typów powinna być podobna do no operation. W ten sposób możesz używać tych obiektów, nie wiedząc, jakiego typu naprawdę są.

Powinieneś także zadać sobie pytanie, czy naprawdę potrzebujesz klasy bazowej, aby być klasą abstrakcyjną. Może potrzebujesz tylko interfejsu. Może być lepsze podejście, ale w oparciu o posiadane informacje i to, co założyłem, wydaje się, że wszystko jest w porządku.

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(); 
} 
Powiązane problemy