2010-05-18 13 views
12

C'è un modo per scoprire il nome della classe derivata da un'istanza di classe base?Come trovare la sottoclasse dall'istanza della classe base?

es .:

class A{ 
    .... 
} 
class B extends A{ 
    ... 
} 
class c extends A{ 
    ... 
} 

ora se un metodo restituisce un oggetto di A, faccio a sapere se è di tipo B o C?

+7

Si noti che [tipo sniffing] (http://www.javapractices.com/topic/TopicAction.do?Id=3) è un po 'un odore di codice. Non è sempre la cosa sbagliata da fare, ma è l'approccio sbagliato abbastanza spesso da dare un'occhiata da vicino al tuo progetto. Se possibile, fai affidamento sul polimorfismo (ma vedi anche [When Polymorphism Fails] di Steve Yegge (http://sites.google.com/site/steveyegge2/when-polymorphism-fails)). – outis

risposta

17

utilizzando instanceof o Class#getClass()

A returned = getA(); 

if (returned instanceof B) { .. } 
else if (returned instanceof C) { .. } 

getClass() sarebbero tornati uno di: A.class, B.class, C.class

All'interno della se-clausola di avresti bisogno di downcast - vale a dire

((B) returned).doSomethingSpecificToB(); 

Detto questo, a volte si ritiene che l'utilizzo di instanceof o getClass() sia una cattiva pratica. Dovresti usare polymorphism per cercare di evitare la necessità di controllare la sottoclasse di calcestruzzo, ma non posso dirti di più con le informazioni fornite.

+1

+1 per picchiarmi. –

+1

Una nota sull'uso del polimorfismo in questa situazione: potreste avere un metodo 'getType()' o qualcosa di simile nell'implementazione di 'A' e sovrascrivere quel metodo in' B' e 'C'. Poiché tutti i metodi sono virtuali in java, una chiamata a 'getType()' risolverebbe il sottotipo specifico. – aioobe

4

Hai provato a usare instanceof

esempio

Class A aDerived= something.getSomethingDerivedFromClassA(); 

if (aDerived instanceof B) { 

} else if (aDerived instanceof C) { 

} 

//Use type-casting where necessary in the if-then statement. 
2

Breve risposta alla tua domanda

C'è un modo per scoprire il nome della classe derivata da un oggetto di classe di base?

non, il super-classe non ha alcun modo di dire il nome/tipo di una sottoclasse.

È necessario interrogare l'oggetto (che è un'istanza di una sottoclasse) e chiedere se è un: instanceof una sottoclasse particolare o chiamare il suo metodo getClass().

0

Ci sono 2 modi che posso pensare 1) Uno con l'utilizzo di Java riflessione API 2) Altro Uno potrebbe essere con l'instanceof

altro metodo può essere un confronto di oggetti a oggetti, non so come potrebbe essere, si può provare questo

0

puoi farlo nella sottoclasse costruttore

class A { 
    protected String classname; 
    public A() { this.classname = "A"; } 
    public String getClassname() { return this.classname; } 
} 
class B extends A { 
    public B() { 
     super(); 
     this.classname = "B"; 
    } 
} 

Così

A a = new A(); 
a.getClassname(); // returns "A" 
B b = new B(); 
b.getClassname(); // returns "B" 
((A)b).getClassname(); // Also returns "B" 

Poiché è inserito in un oggetto "A", chiamerà la funzione "A" getClassname() ma restituirà un valore impostato dal costruttore che era il costruttore "B".

Nota: Call super(); prima di impostarlo

0

C'è un modo per scoprire il nome della classe derivata da un'istanza di classe di base?

come risposta here, è possibile utilizzare questo estremamente semplice approccio.

abstract class A { 
    public final String getName() { 
     return this.getClass().getName(); 
    } 
} 

class B extends A { } 

class C extends A { } 

poi semplicemente stampare la corrente class nome:

B b = new B(); 
C c = new C(); 

System.out.println(b.getName()); 
System.out.println(c.getName()); 

uscita:

com.test.B 
com.test.C 

Non v'è alcuna necessità di memorizzare ulteriore Strings, controllare instanceof o override il metodo in ogni sottoclasse.

Problemi correlati