miércoles, 22 de mayo de 2013

Operador Instanceof y Conversiones de tipo (casting)

Buenas amigos, en este nuevo tema vamos a ver la utilización del operador "instanceof" y las conversiones de tipos. Este tema puede resultar algo complicado de comprender para aquellos que se han iniciado hace relativamente poco a la programación orientada a objetos, y mas concretamente a java, pero realmente es muy sencillo, si se explica bien.



El operador "instanceof" comprueba que un objeto pertenezca a cierta jerarquía de clases. Pongamos un ejemplo:

Poseemos la siguiente jerarquía de clases:

Tenemos una clase "Padre" llamada "Animal", y 2 clases "Hijos" (Gato y Perro) que heredan de ella. Ahora, realizaremos una cuarta clase, la cual será la que realice las acciones pertinentes, en donde crearemos un método que acepte solamente objetos de tipo "Animal".

Supongamos que queremos diferenciar entre un objeto Perro y otro Gato para hacer una acción u otro, pero en el método se pide un objeto de tipo "Animal", ¿Qué hacer? Bien, es sencillo, aplicaremos "polimorfismo":

        • Animal p=new Perro();
        • Animal g=new Gato();

Ambos objetos (p y g) son "Animales", con lo cual podremos incluirlos en el argumento del método, pero cada uno sigue siendo un Perro (p) y un Gato(g) con sus diferencias incluidas.

Ahora, dentro del método, por medio de "instanceof" comprobaremos que tipo de objeto es (Perro o Gato) y realizaremos una acción según pertenezca.

 
Como podéis ver, he creado dos objetos, como mencione anteriormente, y se los he pasado por argumentos al método creado. En él, creamos una sentencia condicional "if" que, por medio del operador "instanceof", nos compara el objeto con la clase, y si coincide nos devuelve "true" y si no, nos devuelve "false".

Comprobemos ahora que ocurriría si tuviésemos un objeto de la clase Perro y comparamos su jerarquía:


Esto anteriormente nos daría "true" y nos imprimiría por pantalla, ya que aunque creemos un objeto de la clase Perro sin utilizar el polimorfismo, sigue heredando de "Animal", con lo cual seguirá perteneciendo a la jerarquía.

Por el contrario, podemos llegar a crear un objeto de la clase "Animal" y comprobar si pertenece a la jerarquía de Perro:


Este código nos dará "false" ya que la jerarquía se comprueba en ascendente, y un "Animal" puede ser un Perro o un Gato, con lo cual no puede saber ciertamente de que tipo de "Animal" se trata.

Si intentamos comparar 2 objetos de distintas jerarquías nos dará error de compilación, ya que no se pueden comparar dos objetos de distintas categorías.


Como veis, Eclipse me marca el error con la linea roja, NO se pueden comparar 2 objetos de distintas jerarquías, un perro nunca será un gato y un gato nunca será un perro, aunque ambos sean animales.

Con las interfaces pasa algo parecido, es decir, aunque no se implemente directamente en la clase es posible estar en su jerarquía aunque solamente se implemente en la clase "padre":


Teniendo esta jerarquía si hacemos lo siguiente, nos dará "true":


Aunque no la implementemos directamente en la clase Perro, si lo está en su clase "Padre" (Animal), por lo tanto pertenece a la misma jerarquía.


Bien, una vez comprobado el tipo de objeto, vamos a hablar de las conversiones de tipo o casting.

Las conversiones de tipo se realizan para indicar el tipo de objeto concreto con el que se va a trabajar. Es decir, le tenemos que indicar sobre que tipo de objeto va a trabajar. Estas pueden ser:
          • Implícitas
          • Explicitas.
Con las conversiones implícitas no hace falta indicarle con que tipo de objeto va a trabajar:


Podéis observar que creo un objeto de la clase Perro y posteriormente se lo paso a Animal, esto esta permitido ya que Animal es la clase Padre y trabaja sobre uno de sus hijos, la conversión de tipo está implícita ya que se comprueba la jerarquía del objeto de manera descendente. ¿Qué pasaría al contrario?


Observar que ahora si que le tengo que hacer la conversión de tipo, ya que la jerarquía de clase se vuelve ascendente y al pasarle el objeto debemos indicarle que le estamos pasando un Animal, pero tenemos que tratarlo como si fuera un Perro, por lo tanto esta explicito como queremos tratarlo. 

Tenemos que tener cuidado porque el siguiente código compila bien pero produce una excepción:


Con esto cuidado, que compila muy bien pero peta.

Esto no solo funciona así en estas clases, java funciona así, para todo tipo de datos, pongamos un ejemplo con datos primitivos:


Bueno, veréis que tengo una variable double con un valor de 10.4, posteriormente paso la variable d a una variable de tipo entero, y como las variables de tipo entero tiene que ascender de jerarquía para obtener el valor de la variable double, debemos de hacerle una conversión de tipo explicita. Posteriormente imprimiremos el valor de i por pantalla y comprobaremos que nos da un valor de 10. OJO con esto, aunque sea muy poco apreciable, hemos perdido información en el proceso de la conversión, hemos pasado de 10.4 a 10, de igual manera hubiésemos obtenido más información si el valor de double hubiese sido 10.6, ya que el redondeo nos hubiese salido 11, con esto solo quiero indicar que tengáis cuidado al utilizar las conversiones de tipo o casting.

Bueno, esto es un poco pesado y mucha gente pasara de este tema, pero son cosas que hay que saber, y son importantes por muy pesadas que las veáis. Por mi parte es todo, espero haber sido lo más claro posible.

Un saludo.

No hay comentarios:

Publicar un comentario