2009-05-17 21 views
2

Ich habe zwei Klassen A und B, wobei B eine Unterklasse von A ist und A nicht abstrakt ist. Daher kann ich Objekte haben, die eine Instanz von A sind und Objekte, die eine Instanz von B (und daher von A) sind.Die spezifischste Unterklasse für ein Java-Objekt?

Wie kann ich Objekte unterscheiden, die nur eine Instanz von A sind?

Sicher kann ich etwas wie "Objekt instaceof A & &! (Objektinstanz von B)" schreiben, aber das ist ein sehr schlechter Entwurf, da ich den Code jedes Mal ändern muss, wenn ich neue Unterklassen zu A hinzufüge. Bessere Alternativen?

Antwort

7
object.getClass() == A.class 
2

Zeigt das nicht, dass B nicht wirklich ein A ist? Ich bin nicht ganz sicher, dass Sie in diese Situation geraten sollten? Vielleicht könnten Sie Ihr Design verbessern?

5

Warum möchten Sie sie unterscheiden? Normalerweise ist dies das Gegenteil von OO. Sie haben verschiedene Instanzen, die Sie nicht unterscheiden müssen, weil die unterschiedliche Implementierung alles richtig macht.

Wenn Sie dies tun müssen, sollte es ein Protokoll dafür geben. Habe zu diesem Zweck eine Methode, die etwas wiedererkennt. Das ist auch flexibler.

Ich würde instanceOf und getClass betrachten bereits schlechter Stil, wenn dies ohne Grund verwendet wird

+0

+1 mit Ihrer Antwort. Java ist eine statische Sprache, wenn Sie den dynamischen Typ Ihrer Objekte berücksichtigen müssen, sehen Sie sich das Besuchermuster an. – pgras

+0

das sieht aus wie Fall des Dispatcher-Muster in sehr OO-Art gelöst werden. Das Muster ermöglicht unterschiedliche Verhaltensweisen abhängig vom Objekttyp, aber ich bin mir nicht sicher, ob dies in Java möglich ist. IMHO Sprachen brauchen bessere Unterstützung für Meta-Programmierung ... –

2

Ein besserer Ansatz ist der Test das Ergebnis eines Verfahrens

class A { 
    public boolean isSomeTest() { 
     return true; 
    } 
} 
class B extends A { 
    public boolean isSomeTest() { 
     return false; 
    } 
} 

dann zu machen, wenn Sie eine C hinzufügen was erweitert A Sie können zulassen, dass es wahr oder falsch zurückgibt.

Der Name von isSomeTest sollte klarstellen, was die Rückgabe von true oder false bedeuten sollte.

2

Dies ist, was ich denke, Sie sagen:

public class A { 
} 

public class B extends A { 
} 

später im Code:

A apple = new A(); 
B banana = new B(); 

Hier sind einige Optionen, die Sie nützlich finden können: In Bezug auf

if (apple.getClass() == A.class) { // Found an A } 
if (banana.getClass() == A.class) { // This is not an A, won't get here. } 
if (apple instanceof A) { // This is definitely an A } 
if ((apple instanceof A) && (!(apple instanceof B))) { // It's an A but not a B } 

die letzte Option, schreiben Sie folgendes:

Klar, kann ich so etwas wie „Objekt instaceof A & &! (Objekt Instanz B)“ schreiben, aber das ist ein sehr schlechtes Design, da ich jedes Mal den Code ändern müssen werde ich neue hinzufügen Unterklassen zu A. Bessere Alternativen?

Polymorphie hilft uns fast immer hier. Ihr Punkt, den Code jedes Mal zu ändern, wenn Sie eine Unterklasse hinzufügen, ist genau die Art von Symptomen, die Sie als standardmäßige objektorientierte Designentwicklung erkennen sollten. Denken Sie über das Verhalten nach, das Sie erzeugen möchten. Kannst du das in die Klasse selbst schieben, anstatt sie an einen externen Anbieter zu delegieren, der herausfinden muss, an welcher Klasse er gerade arbeitet?

Ohne weitere Informationen, kann ich nicht zu viel gebend, aber hier ist ein ziemlich einfaches Beispiel:

// Instead of this 
if (apple.isClassA()) { // run class A code 
} else if (apple.isClassB()) { // run class B code 
// And so forth 
} 

das Design ändern eher wie dieses werden:

public class A { 
    public void executeCommand() { 
     // run class A code 
     // This method knows that it's definitely an A, not a B 
    } 
} 

public class B extends A { 
    public void executeCommand() { 
     // run class B code 
     // This method knows that it's a B (and, therefore, an A as well). 
    } 
} 

Wo später in der Ausführungscode, ersetzen Sie Ihren vorherigen if-Test durch:

apple.executeCommand(); 
banana.executeCommand(); 

Ad Kurz gesagt, dies ist eine fast triviale objektorientierte Design-Überprüfung, aber es kann etwas locker und helfen Sie mit Ihrem Problem Subclassing.

+2

Warum würde eine Banane Unterklasse einen Apfel? – Catchwa

+0

Ja, das ist zugegebenermaßen ein lustiger Gedanke. Vielleicht versuche ich, verschiedene Sorten von Kindersaftdosen direkt am Baum genetisch zu konstruieren. Ich habe versucht, die "Standard" scheußlichen Anhäufung von "Klasse A" und "A theA" zu vermeiden; oder "A aA" Stattdessen steht A für Apfel, B für Banane. Wenn Sie an eine Vielzahl von Äpfeln denken können, die mit B beginnen, werde ich sie ändern. –

0

die getClass Methode eines Objekts Verwenden Sie gegen die Klasse Eigenschaft:

if(someObject.getClass() == A.class){ 
    //some code 
} 
Verwandte Themen