jueves, 23 de octubre de 2008

3. Conversión de objetos

El polimorfismo visto previamente está basado en utilizar referencias de un tipo más “amplio” que los objetos que los apuntan. Las ventajas del polimorfismo son evidente, pero hay una importante limitación: el tipo de la referencia (clase abstracta, clase base o interfase) limita los métodos que se pueden utilizar y las variables miembros a las que se pueden acceder. Por ejemplo, un objeto puede tener una referencia cuyo tipo sea una interfase, aunque sólo en el caso en que su clase o una de sus super-clases implementen dicha interfase. Un objeto cuya referencia es un tipo de interfase sólo puede utilizar los métodos definidos en dicha interfase. Dicho de otro modo, ese objeto no puede utilizar las variables y los métodos propios de su clase. De esta forma la referencia de tipo interfase define, limitan y unifican la forma de utilizarse de objetos pertenecientes a clases muy distintas (que implementan dicha interfase).
Si se desea utilizar todos los métodos y acceder a todas las variables que las clases de un objeto permite, hay que utilizar un cast explícito, que convierta su referencia más general que en la tipo específico del objeto.
De aquí una parte importante del interés del cast entre objetos (más bien entre referencias, habría que decir).
Para la conversión entre objetos de distintas clases, java exige que dichas clases estén relacionadas por herencia (una deberá ser subclase de la otra). Se realiza una conversión implícita o automática de una subclase a una superclase siempre que se necesite, ya que el objeto de la subclase siempre tiene toda la información necesaria para ser utilizado en lugar de un objeto de la superclase. No importa que la superclase no sea capaza de contener toda la información de la subclase.
La conversión en sentido contrario -utilizar un objeto de una superclase donde se espera encontrar uno de la subclase- debe hacerse de modo explícito y puede producir errores por falta de información o de métodos. Si falta información, se obtiene una ClassCastException.
No puede acceder a las variables exclusivas de la subclase a través de una referencia de la superclase. Sólo se pueden utilizar los métodos definidos en la superclase, aunque la definición utilizada para dichos métodos sea la de la subclase
Por ejemplo, supóngase que se crea un objeto de una subclase B y se referencia con un nombre de una superclase A,
A a=new B ();
En este caso el objeto creado dispone de más información de la que la referencia a le permite acceder (podría ser, por ejemplo, una nueva variable miembro j declarada en B). Para acceder a esta información adicional hay que hacer un cast explícito en la forma (B)a. Para imprimir esa variable j habría que escribir (los paréntesis son necesarios):
System.out.println (((B) a).j);
Un cast de un objeto a la superclase puede permitir utilizar variables –no métodos- de la superclase, aunque estén redefinidos en la subclase. Considérese el siguiente ejemplo: la clase C deriva de B y B deriva de A. las tres definen una variable x. En este caso, si desde el código de la subclase C se utiliza:

X //se accede a la x de C
this.x //se accede a la x de C
super.x //se accede a la x de B. sólo se puede subir un nivel
((B) this).x //se accede a la x de B
((A) this).x //se accede a la x de A

No hay comentarios: