Sunteți pe pagina 1din 8

Universidad Nacional de la Matanza - Taller Java

Manejando Herencias
Traduccin: Lucas Videla Fuente: Tutora de http://java.sun.com/docs/books/tutorial/java/javaOO/subclasses.html La clase Object, definida en el paquete java.lang, define e implementa comportamiento comn a todos los objetos. Como se muestra en la siguiente imagen, muchas clases derivan de Object, muchas clases derivan de esas clases, y as sucesivamente, formando una jerarqua de clases.

Todas las clases son descendientes de Object En la cima de la jerarqua, Object es la ms general de todas las clases. Las clases cerca de la base de la jerarqua proveen un comportamiento ms especializado. Una subclase deriva de otra clase. El trmino superclase se refiere al ancestro directo de una clase, o a cualquiera de sus clases ascendentes. Cada clase tiene una y slo una superclase directa (herencia simple). Una subclase hereda todas las variables y mtodos miembro de su superclase. Sin embargo, la subclase puede no tener acceso a una variable o mtodo heredado. Por ejemplo, una subclase no puede acceder a un miembro privado heredado de su superclase. Uno podra pensar, entonces, que este tem no fue heredado en absoluto. Pero el tem es heredado. Esto se convierte en importante cuando se usa una clase interna (ya se ver el concepto), la cual tiene acceso a los miembros privados de la clase que la incluye. Ntese que los constructores no son miembros y por lo tanto no son heredados por subclases.

Universidad Nacional de la Matanza - Taller Java

Sobreescribiendo mtodos
Un mtodo de instancia en una subclase con la misma firma y tipo de retorno que el mtodo de instancia de la superclase sobreescribe el mtodo de la superclase (Record que la firma de un mtodo es el nombre y el nmero y tipo de parmetros). La habilidad de una subclase para sobreescribir un mtodo le permite a la clase heredar desde una superclase aqul comportamiento que es suficientemente cercano y luego modificar el comportamiento com sea necesario. Por ejemplo, la clase Object contiene un mtodo de instancia llamado toString que devuelve una cadena representando la instancia de ese tipo. Cada clase hereda este mtodo. La implementacin en Object no es muy til para las subclases; entonces, recomendamos sobreescribir este mtodo para preveer mejor informacin para tus clases. Es particularmente til para debuguear (quitar errores). Aqu hay un ejemplo de sobreescritura del toString: public class MiClase { private int unEntero = 4; //Sobreescribimos el mtodo toString public String toString() { return "Instancia de MiClase. unEntero = " + unEntero; } } El mtodo que sobreescribe tiene el mismo nombre, nmero y tipo de argumentos, y devuelve un valor del mismo tipo que el mtodo que est sobreescribiendo (de hecho, el tipo que devuelve una subclase puede ser una subclase del tipo que devuelve la superclase. Pero ese es otro tema). El mtodo que sobreescribe puede tener diferentes throws (lanzamientos de excepciones) en su definicin mientras no especifique ningn tipo no especificado en la clusula throws del mtodo sobreescrito. Adems, el especificador de acceso para el mtodo que sobreescribe puede admitir ms pero no menos acceso que el mtodo sobreescrito. Por ejemplo, un mtodo protegido en la superclase puede ser pblico pero no privado en la subclase. Una subclase no puede sobreescribir mtodos declarados como final en la superclase (por definicin, los mtodos final no pueden ser sobreescritos). Ya veremos cmo escribir mtodos final. Una subclase debe sobreescribir los mtodos que son declarados como abstractos en la superclase, o la subclase asimismo ser abstracta. El tema de clases abstractas se dar en otra oportunidad. Tambin se puede hacer lo que se conoce como sobrecargar mtodos, mediante la escritura de nuevos mtodos que tengan distinto nmero o tipo de argumentos. Adems se pueden sobrecargar mtodos en una superclase. Aqu hay un ejemplo de sobrecarga del mtodo toString. public class MiClase { private int unEntero = 4; //Sobreescribimos el mtodo toString public String toString() { return "Instancia de MiClase. unEntero = " + unEntero; } //Sobrecargamos el mtodo toString public String toString(String prefijo) { return prefijo + "Instancia de MiClase. unEntero = " + unEntero; } }

Universidad Nacional de la Matanza - Taller Java

Como ilustra el ejemplo anterior, se debe sobrecargar un mtodo de una superclase para proveer funcionalidad adicional. Cuando se escribe un mtodo que tiene el mismo nombre que en la superclase, se debe chequear doblemente los valores de retorno y listas de argumentos para estar seguro si se est sobrecargando o sobreescribiendo, lo que se hubiera pretendido. Por ltimo, debemos destacar que un mtodo de instancia no puede sobreescribir a un mtodo de clase, y un mtodo de clase no puede sobreescribir un mtodo de instancia. La siguiente tabla resume qu sucede cuando se define un mtodo de la misma firma que un mtodo en una superclase: Mtodo de Instancia en Superclase Mtodo de Instancia Mtodo de Clase Sobreescribe Genera un error en tiempo de compilacin Mtodo de Clase en Superclase Genera un error en tiempo de compilacin Esconde el mtodo

Escondiendo variables miembro


Dentro de una clase, una variable miembro que tiene el mismo nombre que una variable miembro en una superclase esconde la variable miembro de la superclase, an si sus tipos son diferentes. Dentro de la subclase la variable miembro de la superclase no puede ser referenciada simplemente por su nombre. En cambio, la variable miembro debe ser accedida a travs de la palabra super, la cual es examinada en la siguiente seccin. En lneas generales, no recomendamos esconder variables miembro.

Universidad Nacional de la Matanza - Taller Java

Utilizando super
Si tu mtodo sobreescribe uno de los mtodos de su superclase, an pods invocar el mtodo sobreescrito mediante el uso de super. Adems pods usar super para referirte a una variable miembro escondida. Consideremos esta superclase: public class Superclase { public boolean unaVariable; public void unMetodo() { unaVariable = true; } } Ahora, aqu est la subclase, que sobreescribe el mtodo y la variable: public class Subclase extends Superclase { public boolean unaVariable; // esconde unaVariable en Superclase public void unMetodo() { unaVariable = false; super.unMetodo(); System.out.println(unaVariable); System.out.println(super.unaVariable); } } Dentro de la Subclase, el nombre unaVariable se refiere a la que est declarada en la Subclase. De manera similar, el nombre unMetodo se refiere al que est declarado dentro de la Subclase, el cual sobreescribe al de la Superclase. Entonces, para referirse a unaVariable y a unMetodo heredados desde la Superclase, la Subclase debe usar una palabra reservada, super, como se mostr. Luego, la salida de la invocacin al mtodo unMetodo de la Subclase muestra lo siguiente: false true El siguiente ejemplo muestra cmo usar la palabra reservada super para invocar al constructor de la superclase. Supon que ests escribiendo un sistema basado en transacciones y necesits arrojar una excepcin si la transaccin falla. Como una excepcin debe inclur un mensaje informativo y una referencia a la causa del problema, otra excepcin, chequeada o no chequeada (Throwable). public final class TransactionFailedException extends Exception { static final long serialVersionUID = -8919761703789007912L; public TransactionFailedException(Throwable cause){ super(Transaction failed,cause); } } La lnea en negrita es una invocacin explcita al constructor de la superclase, que llama al constructor provisto por la clase Exception. Exception tiene cuatro constructores, y este en particular invoca a la versin que toma como argumentos una cadena y un Throwable. Si est presente, la invocacin explcita al constructor de la superclase debe ser la primera instruccin en el constructor de la subclase. Si un constructor no invoca explcitamente al constructor de la superclase, el compilador de Java automticamente inserta una llamada al constructor sin argumentos de la superclase.

Universidad Nacional de la Matanza - Taller Java

Ser descendiente de Object


La clase Object est en la cima del rbol de jerarqua. Cada clase es un descendiente, directo o indirecto, de la clase Object. Esta clase define el estado y comportamiento bsico que todos los objetos deben usar, as como la habilidad de compararse con otro objeto, convertirse en una cadena, esperar una condicin variable, notificar a otros objetos que una condicin variable ha cambiado y devolver la clase de un objeto. La clase Object provee gran cantidad de mtodos tiles que pueden necesitar ser sobreescritos por una clase con comportamientos definidos. Los principales son: clone equals hashCode toString En adicin, la clase Object provee los siguientes mtodos prcticos: getClass notify, norifyAll, wait Con excepcin de las ltimas tres, estos mtodos sern cubiertos en esta seccin. Los ltimos tres mtodos dependen de la seccin en que hablemos de sincronizacin entre objetos, y eso ser discutido luego. El mtodo clone Nota: S cauteloso cuando implementes el mtodo clone, ya que puede traer consecuencias inesperadas. Se utiliza el mtodo clone para crear un objeto desde otro objeto preexistente. Para crear un clon, debs escribir: unObjetoClonable.clone(); La implementacin en Object de este mtodo chequea para ver si el objeto que invoca al mtodo est implementando la interfase Cloneable. Si el objeto no lo hace, el mtodo arroja una CloneNotSupportedException. An cuando Object implementa el mtodo clone, la clase Object no est declarada como implementando la interfase Cloneable, entonces las clases que no implementen explcitamente esta interfaz, no son clonables. Si el objeto desde el que se invoca el mtodo clone implementa la interfase Cloneable, la implementacin de Object del mtodo clone crea un objeto de la misma clase que el original, e inicializa las variables miembro del nuevo objeto para tener los mismos valor que las correspondientes en el objeto original (vern la similitud con el Constructor de Copia en C++). La manera ms simple de hacer tu clase clonable, entonces, es agregar en la declaracin las palabras implements Cloneable. Para algunas clases, el comportamiento por defecto del mtodo clone en Object trabaja bien. Otras clases necesitan sobreescribir el mtodo para obtener un funcionamiento correcto. Por ejemplo, la clase Stack, la cual incluye una lista, debera sobreescribir el mtodo para un correcto funcionamiento. Para quien no se di cuenta por qu, aqu va la explicacin: Por definicin, el mtodo clone de la clase Object copia uno a uno los contenidos de las variables del objeto a clonar. Qu suceder con la referencia a la lista? Exactamente, se copiar una referencia a la misma lista, lo cual no es el comportamiento adecuado (al fin y a l cabo no est clonando). Debera lograrse que se clonen todas las variables, y luego, llamar al mtodo clone para clonar la lista tambin.

Universidad Nacional de la Matanza - Taller Java

Nota: El mtodo clone no debe nunca usar new para crear un clon y no debe llamar a constructores. En cambio, el mtodo debe llamar a super.clone, el cual crea un objeto del tipo correcto y permite a la jerarqua de superclases realizar la copia necesaria para obtener un clon adecuado. Los mtodos equals y hashCode El mtodo equals compara dos objetos por igualdad y devuelve verdadero si son iguales. El mtodo provisto por la clase Object usa el operador de identidad (==) para determinar cundo dos objetos son iguales. Si los objetos comparados son exactamente el mismo objeto, el mtodo devuelve verdadero. Sin embargo, para algunas clases, dos objetos distintos de un tipo en particular deben ser considerados iguales si contienen la misma informacin. Aqu hay un ejemplo: Supongamos que tenemos varias instancias de Libro, los cuales tienen entre sus atributos el ISBN, nombre, autor, precio, ubicacin... los datos tpicos que tendra en una librera. Ahora bien, dos libros son iguales si sus ISBN son iguales (as como dos alumnos son iguales si sus DNIs concuerdan, y muchas analogas similares). En este caso, deberamos sobreescribir el mtodo equals para que compare nicamente los ISBN, los que, al ser iguales, generarn una salida verdadera. De no ser as, la salida ser falsa. Siempre deberas sobreescribir el mtodo equals si el operador de identidad no es apropiado para tu clase. Y si sobreescribs equals, sobreescrib hashCode tambin. El valor devuelto por hashCode es un entero que mapea un objeto dentro de una categora en una hashTable (ya se ver el Java Collections Framework). Un objeto debe siempre producir el mismo cdigo de Hashing. Sin embargo, los objetos pueden compartir cdigos de Hashing (no son necesariamente nicos). Escribir una funcin de hashing correcta es fcil (siempre retornar el mismo cdigo para el mismo objeto). Escribir una funcin de hashing eficiente (una que provea una buena distribucin de los objetos dentro de las categoras) es dificultoso y est fuera del alcance de este apunte. As y todo, la funcin de hashing para algunas clases es relativamente obvia. Por ejemplo, un cdigo de hashing obvio para un objeto Integer es el valor entero que representa. El mtodo toString El mtodo toString de la clase Object devuelve una cadena representando un objeto. Pods usar toString junto con System.out.println para mostrar una representacin textual de un objeto, como por ejemplo, la instancia de un Libro: System.out.println(miLibro.toString()); el cual, esperemos, imprima algo til, como esto: 0201914670: The JFC Swing Tutorial: A Guide to Constructing GUIs, 2nd Edition Authors: Kathy Walrath, Mary Campione, Alison Huml, Sharon Zakhour La representacin en cadena para un objeto depende enteramente del objeto. El mtodo toString es muy til cuando se quitan errores. Deberas sobreescribir este mtodo en todas tus clases.

Universidad Nacional de la Matanza - Taller Java

El mtodo getClass El mtodo getClass devuelve una representacin en tiempo de ejecucin de la clase de un objeto. El mtodo devuelve un objeto del tipo Class, al cual se le puede pedir informacin sobre la clase, como ser su nombre, su superclase, y la interfaz que implementa. No pods sobreescribir el mtodo getClass. Un ejemplo de invocacin sera el siguiente: miObjeto.getClass().getSimpleName();

Escribiendo mtodos y clases final


Pods declarar algunos o todos de tus mtodos como final. La palabra reservada final en la declaracin de un mtodo indica que el mtodo no puede ser sobreescrito por las subclases. La clase Object hace esto; algunos de sus mtodos son final, y otros no. Podras desear hacer un mtodo como final si tiene una implementacin que no debe ser cambiada y es crtica para el estado consistente del objeto. Los mtodos llamados desde constructores generalmente deben ser declarados final. Si un constructor llama a un mtodo no-final, una subclase podra redefinir ese mtodo para que se comporte en forma sorpresiva o incluso no deseada. Ntese que tambin se puede declarar a la clase completa como final (esto evita que la clase sea heredada). Esto podra ser particularmente til cuando se crea una clase inmutable, como la clase String.

Universidad Nacional de la Matanza - Taller Java

Escribiendo clases y mtodos abstractos


Clases abstractas A veces, una clase que defins representa un concepto abstracto y, como tal, no debe ser instanciado. Tomemos, por ejemplo, la comida. Alguna vez viste una instancia de Comida? Probablemente no. Lo que ves en cambio son instancias de Zanahoria, Manzana, y GalletitasChocolate. Comida representa el concepto abstracto de lo que podemos comer. No tiene sentido la existencia de una instancia de Comida. De manera similar, en la programacin orientada a objetos, podras querer modelar un concepto abstracto sin ser capaz de crear una instancia de ello. Por ejemplo, la clase Number representa el concepto abstracto de nmeros. Tiene sentido modelar nmeros, pero no tiene sentido crear un objeto nmero genrico. En cambio, la clase Number tiene sentido slo como superclase para clases como Integer y Float, ambas que implementan tipos especficos de nmeros. Una clase como Number, la cual representa un concepto abstracto y no debe ser instanciada, es conocida como clase abstracta. Una clase abstracta slo puede ser heredada. Para declarar una clase como abstracta, se utiliza la palabra reservada abstract antes de la palabra reservada class en la declaracin de la clase: abstract class Number { //... } Si intents instanciar una clase abstracta, el compilador muestra un mensaje de error. Mtodos abstractos Una clase abstracta puede contener mtodos abstractos, es decir, mtodos sin implementacin. De esta manera una clase abstracta puede definir completamente una interfase de programacin para sus subclases pero deja a ellas los detalles de implementacin de esos mtodos. En la prctica, las clases abstractas proveen una completa o parcial implementacin de al menos un mtodo. Si una clase abstracta contiene slo declaraciones de mtodos abstractos, debera ser implementada como una interfase. Por ejemplo, en una clase abstracta Figura, podra existir un mtodo implementado denominado mover, el cual sera de igual funcionalidad para cualquier Figura que se cree. En cambio, un mtodo llamado dibujar debera ser abstracto, ya que no tendr la misma implementacin para cada subclase de la clase Figura (un Circulo no se dibuja de la misma manera que un Cuadrado o una Linea). Una clase abstracta no requiere tener un mtodo abstracto dentro. Pero cualquier clase que tiene un mtodo abstracto dentro, o que no provee implementacin para cualquier mtodo abstracto declarado en su superclase, debe ser declarada como clase abstracta.

S-ar putea să vă placă și