2010-11-04 7 views
24

En Java, ¿cómo hago para determinar qué clases abarca una clase?¿Cómo puedo determinar si una clase amplía otra clase en Java?

public class A{ 
} 

public class B extends A{ 
} 

public class C extends A{ 
} 

public class D{ 
} 

public class E extends B{ 
} 

public class doSomething{ 

    public void myFunc(Class cls){ 
     //need to check that cls is a class which extends A 
     //i.e. B, C and E but not A or D 
    } 
} 

would cls.getSuperClass() hacer lo que necesito?

Respuesta

48

El acercamiento getSuperClass() fallaría para E ya que su superclase inmediata no es A, sino B. Más bien use Class#isAssignableFrom().

public void myFunc(Class cls){ 
    //need to check that cls is a class which extends A 
    //i.e. B, C and E but not A or D 

    if (cls != A.class && A.class.isAssignableFrom(cls)) { 
     // ... 
    } 
} 
+0

Esta es de lejos la mejor solución sugerida, pero me gustaría añadir que tratar de hacer esto es un poco "olor a código". Es posible que desee tratar de encontrar una mejor manera de hacerlo, como sugiere Martin Broadhurst. –

+0

@Justin: me doy cuenta de eso también. Desafortunadamente, el argumento es 'Clase 'y el requisito establece que''Aclase' en sí no debería pasar el cheque. Lo mejor sería hacer que 'A' sea abstracto y aplicar el patrón de estrategia, pero eso requiere una instancia * concreta * de 'A' como argumento, no 'Clase '. No estoy seguro de cómo afectaría eso al remanente del diseño de OP. Tal vez el OP tiene sus propias razones válidas para elegir 'Clase' como argumento. El requisito funcional tiene que aclararse más antes de que podamos dar mejores sugerencias de diseño. – BalusC

+0

¿Se está utilizando esto para un sistema de negocios real o un proyecto escolar? –

5

Sí, Class.getSuperclass() es exactamente lo que necesita.

Class<?> c = obj.getClass(); 
System.out.println(c.getSuperclass() == Some.class); 
+0

¿Desea == o igual (o no importa para los objetos de la clase)? –

+2

y para la clase E tendré que iterar por el árbol? –

+2

@sprocketonline - Sí. – Jeremy

8

Usted debe tratar de evitar la comprobación de tipos y en lugar de poner en práctica las funciones de B, C y E que hacer lo que quiere, tiene las versiones A y D no hacen nada, y luego llamar a esa función desde dentro de su clase doSomething.

Si escribe la verificación no es muy fácil de mantener porque cuando agrega nuevas clases necesita cambiar la lógica condicional.

Este es el problema que las clases y las anulaciones están ahí para evitar.

0

Si desea compilar comprobación de tiempo, puede utilizar los genéricos (Java 5 en adelante):

public void myFunc(Class<? extends A> cls) { 
} 

pasar en cualquier clase no heredado de A genera un error de tiempo de compilación.

Cuestiones relacionadas