interface Base { } 
 
class Derivado1 implements Base { 
   int n = 5; 
} 
 
class Derivado2 extends Derivado1 { 
   String s = "hola"; 
} 
 
void main( ) { 
   Derivado1 d1 = new Derivado1( ); 
   Derivado2 d2 = new Derivado2( ); 
   Base[] arr = { null, d1, d2 };         // el elemento extra al inicio es para que d1 esté en el indice 1 y d2 esté en el índice 2 
 
   Scanner sc = new Scanner(System.in); 
   int opcion = sc.nextInt( );            // pedir un índice (1 para d1, 2 para d2) 
   Base p = arr[opcion]; 
 
   if (p instanceof Derivado1) { 
      System.out.println("Compatible con Derivado1"); 
   } 
   if (p instanceof Derivado2) { 
      System.out.println("Compatible con Derivado2"); 
   } 
 
   if (p.getClass( ) == Derivado1.class) {               // .getClass( ) devuelve un apuntador a un objeto de tipo Class que denota su tipo exacto 
      System.out.println("Exactamente un Derivado1");    // el lenguaje garantiza que .getClass( ) y .class sobre el nombre de un tipo apuntan al mismo objeto si se trata de la misma clase 
   } 
   if (p.getClass( ) == Derivado2.class) { 
      System.out.println("Exactamente un Derivado2"); 
   } 
} 
