2013-02-12 21 views
5

Ich habe eine Liste von Objekten, die sich von einer Basisklasse erstrecken. Jetzt möchte ich eine bestimmte Operation nur auf eine Instanz von Klassen in der Liste anwenden. Ist die Verwendung von instanceof eine gute Praxis? Oder sollte ich lieber die Objekte zB durch eine benutzerdefinierte enum unterscheiden?Ist ein Beispiel für eine gute Praxis?

Wenn dieser Ansatz im Allgemeinen nicht so nett ist, wie könnte ich es besser machen?

+6

Polymorphie verwenden; deshalb existiert es. –

+0

genau - statt doSomething (Basis) - sollten Sie einige base.doSomething() implementieren, die in foo.doSomething() überschrieben wird. Google Polymorphismus Java - oder - überschreiben Methode Java. –

+3

Ich mag diese besondere Antwort: http://www.javapractices.com/topic/TopicAction.do?Id=31. Ich weiß, dass C++ und Java anders sind, aber ** "Immer wenn Sie den Code des Formulars schreiben" wenn das Objekt vom Typ T1 ist, dann tun Sie etwas, aber wenn es vom Typ T2 ist, dann machen Sie etwas anderes, "schlagen Sie sich selbst. * * – thang

Antwort

3

Es scheint wirklich keinen Grund zu geben, Instanz von hier zu verwenden. Es kann sinnvoll sein, dass die Basisklasse das Verhalten auf "nichts tun" setzt und sie bei der Erweiterung von Klassen bei Bedarf überschreibt. Auf diese Weise überschreiben Sie es nur bei Bedarf (ich überlasse dies als eine abstrakte Klasse, um der Frage zu folgen, die für dieses Beispiel nicht benötigt wird). Zum Beispiel:

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

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

public class B1 extends Base{} 

Ein Beispiel dieses verwenden, wie etwas sein könnte:

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

Das ist eine sehr nette Idee, da kann ich dann die Implementierung auf Klassen auslassen, die bei diesem Methodenaufruf einfach nichts tun sollten. – 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(); 
} 

Um Ihre Frage zu beantworten: es ist keine gute Idee, instanceof zu verwenden.

+3

Warum prüfen Sie jetzt auf instanceof .. Sie müssen nicht – smk

+2

Falsche Syntax, sollte es sein "base instanceof Bar" – shuangwhywhy

+0

Warum benutzt du instanceof wenn es keine gute Idee ist ?? – membersound

1

Instanz von hier keine gute Praxis ist.

Die richtige Lösung hängt davon ab, was genau in dieser doSomething-Methode vor sich geht. Wenn Sie es auf Ihre Weise tun, verletzen Sie neben anderen Dingen auch Liskov Substitution Principle. Ich nehme an, dass Sie entschieden haben, dass Sie diese Hierarchie an erster Stelle wegen etwas brauchen, und ich nehme auch an, dass Subtypen mehr Verhalten als nur DoSomething-Methode haben. In diesem Fall sehen Sie, was Sie tun können. Grundsätzlich nur Typen, die eigentlich doSomething tun sollten und der Rest der Typen machen so etwas wie no operation. Auf diese Weise können Sie diese Objekte verwenden, ohne zu wissen, um welchen Typ es sich handelt.

Sie sollten sich auch fragen, ob Sie die Basisklasse wirklich als abstrakte Klasse benötigen. Vielleicht brauchst du nur eine Schnittstelle. Es könnte einen besseren Ansatz geben, aber basierend auf den Informationen, die ich habe und was ich angenommen habe, scheint dies in Ordnung zu sein.

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(); 
} 
Verwandte Themen