J'ai une classe de base, Statement
, dont plusieurs autres classes héritent, nommée IfStatement
, WhereStatement
, etc ... Quelle est la meilleure façon d'effectuer un test dans un if
instruction pour déterminer de quelle sorte de Statement
une instance est dérivée?
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
La bonne chose à propos de cette technique (par opposition au mot-clé "instanceof") est que vous pouvez passer la classe de test en tant qu'objet. Mais, oui, à part ça, c'est identique à "instanceof".
REMARQUE: j'ai délibérément évité de rédiger un article sur la question de savoir si la vérification de type d'instance est la droite chose à faire. Ouais, dans la plupart des cas, il vaut mieux utiliser le polymorphisme. Mais ce n'est pas ce que le PO a demandé, et je ne fais que répondre à sa question.
if(object instanceof WhereStatement) {
WhereStatement where = (WhereStatement) object;
doSomething(where);
}
Notez qu'un code comme celui-ci signifie généralement que votre classe de base n'a pas de méthode polymorphe. c'est-à-dire que doSomething()
doit être une méthode de Statement
, éventuellement abstraite, qui est remplacée par des sous-classes.
La réponse à votre question est instanceof.
Cependant, gardez à l'esprit que si votre code nécessite instanceof, c'est le signe que quelque chose ne va pas avec votre conception. Il y a des cas où instanceof est justifiée, mais ce sont plutôt des exceptions. Habituellement, si vos sous-classes doivent se comporter différemment, vous devez utiliser le polymorphisme au lieu de if () s.
isAssignableFrom (Java.lang.Class) de la classe est votre réponse. http://download.Oracle.com/javase/6/docs/api/Java/lang/Class.html#isAssignableFrom (Java.lang.Class )
Essaye ça:
if (Statement.class.isInstance(obj)) {
doStuffWithStatements((Statement) obj));
}
puisque la méthode Class.isInstance () prend une instance d'objet comme paramètre.
C'est pas la façon de faire les choses d'une manière orientée objet, c'est un retour à l'ancienne dichotomie code/données. Ce n'est pas nécessairement une mauvaise chose (si vous savez ce que vous faites) mais cela devrait être laissé aux langages non orientés objet comme C.
Avec une conception appropriée, vous n'avez pas besoin de ce genre de comportement. Au lieu de la construction:
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
(excuses à benjismith pour avoir `` volé '' son code), vous devriez vraiment rendre l'objet lui-même responsable de ses propres activités ainsi:
obj.doStuff();
Ensuite, chaque classe obj
différente aura sa propre définition pour doStuff
. C'est la bonne façon de procéder.