2012-04-14 5 views
0

ich eine Art spezielles Problem haben, lassen Sie uns sagen, dass ichJava - die Art der Klasse herauszufinden, welche von anderen Klassen implementiert

public interface A { 
} 

//------------------------------ 

public class B implements A { 

    static int countx = 0; 
} 

//---------------------------------- 
public class C implements A { 

    static int county = 0; 
} 

//---------------------------------- 

public class Arc { 

    public A from; 
    public A to; 

//======================================== 

und jetzt habe ich ein Objekt ein (das ist eine Instanz Arc) und ich möchte herausfinden, ob es eine Instanz von B oder C ist und zu den Attributen countX oder countY (stg wie a.from.countX) irgendwelche Ideen? :)

+1

Es gibt keine Beziehung zwischen den Klassen 'Arc' und' A' in Ihrer Hierarchie. – Tudor

+0

Sind Sie sicher, dass Sie zwei A's in Arc haben? –

Antwort

1

Ich glaube, Sie instanceof verwenden könnten, dieses Problem zu lösen

wie in

if(a instanceof B) return a.countx 
if(a instanceof C) return a.county 
+0

Dies funktioniert nicht ohne eine Typumwandlung. (Oder tatsächlich in diesem Fall, weil 'countx' und' county' beide statisch sind, was wahrscheinlich ein Fehler/Missverständnis von der OP-Seite ist.) – Anthales

0

Wenn Sie ein Objekt, das eine Instanz von Arc ist, wie ist es dann auch eine Instanz von B oder C? Ich habe den Eindruck, dass Ihr Code fehlerhaft ist und einer Umstrukturierung bedarf. Zum Beispiel wies Tudor darauf hin: "Es gibt keine Beziehung zwischen den Klassen Arc und A in Ihrer Hierarchie."

1

Verwenden instanceof und eine Typumwandlung:

if (a.from instanceof B) { 
    B b = (B)a.from; 
    b.countx; 
} 

Edit: Aber Sie sollten nicht brauchen so etwas wirklich! Wenn Sie das tun, können Sie es wahrscheinlich neu gestalten, um keinen hässlichen Code wie diesen zu erzeugen.

Zum Beispiel könnten Sie Ihre Schnittstelle A eine Methode haben getCount() und lassen Sie Ihre Klassen B und C diese implementieren, indem Sie countx oder county zurückgeben.

Edit2: Ich habe gerade festgestellt, dass Ihre countx und county Mitglieder sind static! Warum würdest du das tun? static bedeutet, dass sie nicht auf Instanzen Ihrer Klasse "agieren", sondern auf Ihr Klassenobjekt (sie sind "Klassenmitglieder"). Dies bedeutet, dass Sie auf diese Variablen überall zugreifen und diese ändern können, indem Sie auf sie über oder B.county zugreifen; Sie wollen dies wahrscheinlich nicht, weil mehrere Instanzen der Klasse Ateilen die gleiche countx!

+0

Also ... könnte es zum Zählen der Anzahl von Instanzen davon verwendet werden bestimmte Klasse. –

+0

Es könnte, wenn Sie die Variable nach dem Erstellen einer neuen Instanz erhöhen (was Sie im Konstruktor tun können) und wenn Sie die Variable nicht öffentlich machen. Der letzte ist wichtig, denn wenn Sie das nicht tun, kann irgendeine zufällige Klasse einfach 'B.countx = -5;' sagen und jetzt haben Sie -5 Instanzen Ihrer Klasse (nicht wirklich natürlich). Deshalb gibt es eine Kapselung von Elementen. – Anthales

+0

Sicher, aber es ist ein kurzer Beispielcode. Ihr Kommentar klingt, wenn statische Elemente/gemeinsamer Status überhaupt nicht verwendet werden. Übrigens sind die Mitglieder im Beispielcode nicht öffentlich. –

1

Ihr aktuelles Design ist aus Sicht der OOP nicht gut. Sie benötigen etwas Einkapselung und Polymorphie. In einer OOP-Sprache überprüfen Sie nicht explizit für den Typ eines Objekts, Sie veranlassen dies automatisch über dynamischen Versand. Also, welche Daten Sie auch von B und C benötigen, fügen Sie der Schnittstelle A eine Methode hinzu, die diese Daten erhält, und implementieren Sie dann die Methode in B und C entsprechend. Verwenden Sie auch keine öffentlichen Instanzfelder, die die Enkapusierung unterbrechen.

+0

Richtige Antwort +1 –

0

Wenn Sie einfach nur Informationen über die Klassen haben wollen:

getClass().getSuperclass() 

Grüße, Erwald

0

Denk darüber wie folgt aus:

Was macht mich wollen zwischen einem B unterscheiden und ein C? Ist es eine Operation? Wenn dies der Fall ist, implementieren Sie diese Operationen einfach in B vs C und lassen Sie sich von dynamischer Verteilung den Rest erledigen.

interface Operation { 
    public Result operate(String[] args); 
} 

class A implements Operation { 

    @Override 
    public Result operate(String[] args) { 
     //I need to do some special calculations for an A...   
     for(String arg : args) { 

     } 
     . 
     . 
     . 
    } 
} 

class B implements Operation { 

    @Override 
    public Result operate(String[] args) { 
     //i know this does nothing so return the empty result 
     return Result.EMPTY; 
    } 
} 

Widerstehen Sie dem Versuch, instanceof zu verwenden.In den meisten Fällen brauchen Sie es nicht - und es ist nicht OO.