2012-12-21 10 views
18

Angenommen akzeptieren Ich habe folgende Klassenstruktur:generische Methode, die nur einen Teil der Klassen

class Base {} 
class A extends Base {} 
class B extends Base {} 
class C extends Base {} 

Ich möchte Methode schreiben, die Instanzen von A und B aber keine Instanzen von C akzeptiert.
Kann ich es in Java erreichen?

Ich weiß, das ist nicht gut Erbe Situation ist (A und B gemeinsamen Mutter unterscheidet sich von C haben sollte), aber ich bin nur in Java Art und Weise neugierig ist Situation wie diese zu behandeln.

BEARBEITEN:
!!!
Ich weiß, dass bessere Vererbung Problem lösen wird. Ich bin nur neugierig, ob Java einen Standardmechanismus hat, um das Problem zu lösen.
!!!

Antwort

3

ich die Antwort auf Ihre Fragen erraten „Nein, Java keinen Standardweg mit einem solchen Umgang Problem". Und wenn Sie dieses Problem haben, können Sie sich hier andere Antworten ansehen, zum Beispiel die Vererbung oder die clevere Technik given by MrSmith42.

+0

Vielen Dank für die richtige und einfache Antwort :) –

+4

@ MichałHerman korrekt? 17 - 1 ... blimy, das ist wie bei der Arbeit. – NimChimpsky

+0

@NimChimpsky mach dir keine Sorgen, es gibt Abzeichen für diese Art von Sache. :) – MikeTheLiar

2

Sie können instanceof verwenden, um zu überprüfen, ob ein Objekt von einem bestimmten Typ ist.

Bessere Idee wäre natürlich bessere Vererbungsstruktur.

+0

zu erlauben, um frei zu sein: In Java funktioniert 'instanceof' für Unterklassen. Das heißt, C c = neu C(); c instanceof B wird wahr zurückgeben. Wenn Sie "C" ausschließen möchten, müssen Sie explizit danach suchen. (Hinzufügen eines Kommentars, weil diese Antwort auf den ersten Blick nicht klar war.) –

13

Können Sie eine Schnittstelle verwenden? z.B.

class Base {} 
interface MyGenericInterface {} 
class A extends Base implements MyGenericInterface {} 
class B extends Base implements MyGenericInterface {} 
class C extends Base {} 

Auf diese Weise kann das Verfahren Implementierungen von MyGenericInterface akzeptieren, und da A und B die Schnittstelle implementieren, aber C nicht der Fall ist, wird es Instanzen von A und B, aber nicht C annehmen, je nach Bedarf.

8

Wenn sollte etwas akzeptieren A, B aber nicht C dann sollten Sie überdenken, warum C von Base in erster Linie vererben. Sie könnten eine zusätzliche Schicht von Vererbung hinzufügen:

---Base--- 
    |  | 
--Sub--  C 
|  | 
A  B 

Dann Sie Ihre Methode nur erlauben könnte, um Objekte von Sub Typ zu akzeptieren. Sub muss nicht einmal etwas tun, und sie sind alle, technisch, auch Base.

Eine schnellere Lösung ein schmutziges if(arg.instanceof(C)) obwohl sein würde ...

8

Sie können es zur Laufzeit behandeln Ausnahme mit:

void genericMethod(Base arg_in) 
{ 
    if(arg_in instanceof C) 
    { 
     throw IllegalArgumentException("C class not accepted."); 
    } 

    ... 
    ... 
} 
8

Ein Typ-Hierarchie sollte nicht nur geändert werden, da Sie haben wollen so eine Methode. Aber der Fall, dass Sie eine solche Methode haben möchten, kann bedeuten, dass Sie über Ihre Typhierarchie denken sollten.

Aber wenn Sie sicher, dass Ihre Typen sind gut gestaltet, was ist mit diesem Ansatz:

public class T { 

     public void doSomething(final A a) { 
      doSomthing(a); 
     } 

     public void doSomething(final B b) { 
      doSomthing(b); 
     } 

     private void doSomthing(final Base b) { 

      // Here is the implementation 

     } 

    } 
+0

Ich weiß nicht, was Sie mit dem Schlüsselwort "final" vorhatten, aber es wird nicht verhindern, dass beim Aufruf eine erweiterte Konvertierung stattfindet Seite? ˅. Da jede Instanz von "C" eine Instanz von "B" ist, wird es immer möglich sein, Instanzen von "C" in Ihre "doSomething()" - Methode zu übergeben. –

+0

Warum denkst du "C ist eine Instanz von B"? A, B, C alle erweitern nur Base – MrSmith42

+0

'final' hat nichts mit der Funktionalität zu tun. Nur eine Code-Konvention, die ich gewohnt bin. – MrSmith42

2

Generics ist für Typ Sicherheit. Zeitraum. Nicht willkürliche Dinge "zulassen" oder "verbieten". Es gibt keinen Typsicherheitsgrund, A und B und nicht C.

Verwandte Themen