Herencia y Polimorfismo

49
Herencia y Polimorfismo

description

Herencia y Polimorfismo

Transcript of Herencia y Polimorfismo

Herencia y Polimorfismo

Herencia y Polimorfismo

En Java, como en otros lenguajes de programacin orientados a objetos, las clases pueden derivar desde otras clases. La clase derivada (la clase que proviene de otra clase) se llama subclase. La clase de la que est derivada se denomina superclase. Subclases, Superclases y Herencia

De hecho, en Java, todas las clases deben derivar de alguna clase. Lo que nos lleva a la cuestin Dnde empieza todo esto?. La clase ms alta, la clase de la que todas las dems descienden, es la clase Object, definida en java.lang. Object es la raz de la herencia de todas las clases. Subclases, Superclases y Herencia

Las subclases heredan el estado y el comportamiento en forma de las variables y los mtodos de su superclase. La subclase puede utilizar los tems heredados de su superclase tal y como son, o puede modificarlos o sobreescribirlos. Por eso, segn se va bajando por el rbol de la herencia, las clases se convierten en ms y ms especializadas. Subclases, Superclases y Herencia

Definicin: Una subclase es una clase que desciende de otra clase. Una subclase hereda el estado y el comportamiento de todos sus ancestros. El trmino superclase se refiere a la clase que es el ancestro ms directo, as como a todas las clases ascendentes. Subclases, Superclases y Herencia

Crear SubclasesSe declara que un clase es una subclase de otra clase dentro de La declaracin de Clase. Por ejemplo, supongamos que queremos crear una subclase llamada SubClase de otra clase llamada SuperClase. Se escribira esto.Subclases, Superclases y Herencia

class SubClass extends SuperClass {..........}Esto declara que SubClase es una subclase de SuperClase. Y tambin declara implcitamene que SuperClase es la superclase de SubClase.Subclases, Superclases y Herencia

Una subclase tambin hereda variables y miembros de las superclases de su superclase, y as a lo largo del rbol de la herencia. Para hacer esta explicacin un poco ms sencilla, cuando nos referimos a la superclase de una clase significa el ancestro ms directo de la clase as como a todas sus clases ascendentes. Subclases, Superclases y Herencia

Una clase Java slo puede tener una superclase directa. Java no soporta la herencia mltiple. Subclases, Superclases y Herencia

Crear una subclase puede ser tan sencillo como incluir la clusula extends en la declaracin de la clase. Sin embargo, normalmente se deber realizar alguna cosa ms cuando se crea una subclase, como sobrescribir mtodos, etc... Subclases, Superclases y Herencia

Qu variables miembro hereda una subclase?Subclases, Superclases y Herencia

Regla: Una subclase hereda todas las variables miembros de su superclase que puedan ser accesibles desde la subclase (a menos que la variable miembro est oculta en la subclase). Subclases, Superclases y Herencia

Esto es, las subclases. heredan aquellas variables miembros declaradas como public o protected heredan aquellas variables miembros declaradas sin especificador de acceso (normalmente conocidas como "Amigas") siempre que la subclase est en el mismo paquete que la claseSubclases, Superclases y Herencia

no hereda las variables miembros de la superclase si la subclase declara una variable miembro que utiliza el mismo nombre. La variable miembro de la subclase se dice que oculta a la variable miembro de la superclase. no hereda las variables miembro privateSubclases, Superclases y Herencia

Ocultar Variables MiembroLas variables miembros definidas en la subclase ocultan las variables miembro que tienen el mismo nombre en la superclase.Subclases, Superclases y Herencia

Como esta caracterstica del lenguaje Java es poderosa y conveniente, puede ser una fuente de errores: ocultar una variable miembro puede hacerse deliberadamente o por accidente. Entonces, cuando nombres tus variables miembro se cuidadoso y oculta slo las variables miembro que realmente deseas ocultar. Subclases, Superclases y Herencia

Una caracterstica interesante de las variables miembro en Java es que una clase puede acceder a una variable miembro oculta a travs de su superclase. Considere este pareja de superclase y subclase. Subclases, Superclases y Herencia

class Super {Number unNumero;}class Sub extends Super { Float unNumero;}

Subclases, Superclases y Herencia

La variable unNumero de Sub oculta a la variable unNumero de Super. Pero se puede acceder a la variable de la superclase utilizando.super.unNumero Subclases, Superclases y Herencia

super es una palabra clave del lenguaje Java que permite a un mtodo referirse a las variables ocultas y mtodos sobreescritos de una superclase. Subclases, Superclases y Herencia

Qu mtodos hereda una Subclase?La regla que especifica los mtodos heredados por una subclase es similar a la de las variables miembro. Regla: Una subclase hereda todos los mtodos de sus superclase que son accesibles para la subclase (a menos que el mtodo sea sobreescrito por la subclase). Subclases, Superclases y Herencia

Esto es, una Subclase. hereda aquellos mtodos declarados como public o protected hereda aquellos mtodos sin especificador de acceso, siempre que la subclase est en el mismo paquete que la clase. no hereda un mtodo de la superclase si la subclase declara un mtodo que utiliza el mismo nombre. Se dice que el mtodo de la subclase sobreescribe al mtodo de la superclase. no hereda los mtodos private. Subclases, Superclases y Herencia

Sobreescribir MtodosLa habilidad de una subclase para sobreescribir un mtodo de su superclase permite a una clase heredar de su superclase aquellos comportamientos "ms cercanos" y luego suplementar o modificar el comportamiento de la superclase. Una subclase puede sobreescribir completamente la implementacin de un mtodo heredado o puede mejorar el mtodo aadindole funcionalidad. Subclases, Superclases y Herencia

Reemplazar la Implementacin de un Mtodo de una SuperclaseAlgunas veces, una subclase querra reemplazar completamente la implementacin de un mtodo de su superclase. De hecho, muchas superclases proporcionan implementaciones de mtodos vacas con la esperanza de que la mayora, si no todas, sus subclases reemplacen completamente la implementacin de ese mtodo. Subclases, Superclases y Herencia

Un ejemplo es el mtodo run() de la clase Thread. La clase Thread proporciona una implementacin vaca para el mtodo run(), porque por definicin, este mtodo depende de la subclase. La clase Thread posiblemente no puede proporcionar una implementacin medianamente razonable del mtodo run(). Subclases, Superclases y Herencia

Para reemplazar completamente la implementacin de un mtodo de la superclase, simplemente se llama a un mtodo con el mismo nombre que el del mtodo de la superclase y se sobreescribe el mtodo con la misma firma que la del mtodo sobreescrito. Subclases, Superclases y Herencia

class ThreadSegundoPlano extends Thread { void run() { . . . } }La clase ThreadSegundoPlano sobrescribe completamente el mtodo run() de su superclase y reemplaza completamente su implementacin. Subclases, Superclases y Herencia

Mtodos que una Subclase no Puede SobrescribirUna subclase no puede sobrescribir mtodos que hayan sido declarados como final en la superclase (por definicin, los mtodos finales no pueden ser sobrescritos). Si intentamos sobrescribir un mtodo final, el compilador mostrar un mensaje similar a este y no compilar el programa. FinalTest.java:7: Final methods can't be overriden. Method void iamfinal() is final in class ClassWithFinalMethod. void iamfinal() { ^ 1 errorSubclases, Superclases y Herencia

Una subclase tampoco puede sobrescribir mtodos que se hayan declarado como static en la superclase. En otras palabras, una subclase no puede sobrescribir un mtodo de clase.Mtodos que una Subclase debe SobrescribirLas subclases deben sobrescribir aquellos mtodos que hayan sido declarados como abstract en la superclase, o la propia subclase debe ser abstracta. Subclases, Superclases y Herencia

Escribir Clases y Mtodos FinalesSe puede declarar que una clase sea final; esto es, que la clase no pueda tener subclases. Existen dos razones por las que se querra hacer esto: razones de seguridad y de diseo. Seguridad: Un mecanismo que los hackers utilizan para atacar sistemas es crear subclases de una clase y luego sustituirla por el original. Las subclases parecen y sienten como la clase original pero hacen cosas bastante diferentes, probablemente causando daos u obteniendo informacin privada. Para prevenir esta clase de subversin, se puede declarar que la clase sea final y as prevenir que se cree cualquier subclase. Subclases, Superclases y Herencia

La clase String del paquete java.lang es una clase final slo por esta razn. La clase String es tan vital para la operacin del compilador y del intrprete que el sistema Java debe garantizar que siempre que un mtodo o un objeto utilicen un String, obtenga un objeto java.lang.String y no algn otro string. Esto asegura que ningn string tendr propiedades extraas, incosistentes o indeseables. Si se intenta compilar una subclase de una clase final, el compilador mostrar un mensaje de error y no compilar el programa. Adems, los bytescodes verifican que no est teniendo lugar una subversin, al nivel de byte comprobando que una clase no es una subclase de una clase final. Subclases, Superclases y Herencia

Diseo: Otra razn por la que se podra querer declarar una clase final son razones de diseo orientado a objetos. Se podra pensar que una clase es "perfecta" o que, conceptualmente hablando, la clase no debera tener subclases. Para especificar que una clase es una clase final, se utiliza la palabra clave final antes de la palabra clave class en la declaracin de la clase. Subclases, Superclases y Herencia

class Mamifero { String especie, color; }class Gato extends Mamifero { int numero_patas; } public class Herencia { public static void main(String[] args) {Gato bisho; bisho = new Gato();bisho.numero_patas = 4;bisho.color = "Negro"; System.out.println(bisho.color); } } Subclases, Superclases y Herencia

Como vemos en el ejemplo, el objeto bisho no slo tiene la propiedad numero_patas, tambin color que es una propiedad de Mamifero. Se dice que Mamifero es la clase padre y Gato la clase hija en una relacin de herencia. Esta relacin se consigue en Java por medio de la palabra reservada extends.Pero, adems de heredad la funcionalidad de la clase padre, una clase hija puede sobreescribirla. Podemos escribir un mtodo en la clase hija que tenga el mismo nombre y los mismos parmetros que un mtodo de la clase padre:Subclases, Superclases y Herencia

class Mamifero { String especie, color; public void mover() { System.out.println("El mamfero se mueve"); } } class Gato extends Mamifero { int numero_patas; public void mover() { System.out.println("El gato es el que se mueve"); } } public class Herencia { public static void main(String[] args) { Gato bisho = new Gato(); bisho.mover(); } } Subclases, Superclases y Herencia

Al ejecutar esta nueva versin veremos que se escribe el mensaje de la clase hija, no el del padre.Conviene indicar que Java es una lenguaje en el que todas las clases son heredadas, an cuando no se indique explcitamente. Hay una jerarqua de objetos nica, lo que significa que existe una clase de la cual son hijas todas las dems. Este Adn se llama Object y, cuando no indicamos que nuestras clases hereden de nadie, heredan de l. Esto permite que todas las clases tengan algunas cosas en comn, lo que permite que funcione, entre otras cosas, el recolector de basura.Subclases, Superclases y Herencia

class Empleado {String nombre;int numEmpleado , sueldo;static private int contador = 0;Empleado(String nombre, int sueldo) {this.nombre = nombre; this.sueldo = sueldo; numEmpleado = ++contador; }public void aumentarSueldo(int porcentaje) { sueldo += (int)(sueldo * aumento / 100); }public String toString() {return "Num. empleado " + numEmpleado + " Nombre: " + nombre + " Sueldo: " + sueldo; } }

class ProductoLimpieza {private String s = new String("Producto de Limpieza");public void aniadir(String a) { s += a; }public void diluir() { aniadir(" diluir() " ) ; }public void aplicar ( ) { aniadir ( " aplicar ( ) " ) ; }public void frotar ( ) { aniadir ( " fregar ( ) " ) ; }public void escribir( ) { System.out.println(s); }public static void main(String[] args) {ProductoLimpieza x = new ProductoLimpieza();x.diluir ( ); x.aplicar ( ); x.frotar ( );x.escribir ( ) ; } }

public class Detergente extends ProductoLimpieza {// Cambiar un mtodo:public void frotar ( ) {aniadir ( " Detergente. frotar ( ) " ) ;super.frotar ( ); }// Llamar a la versin de la clase base// Aadir mtodos al interfaz:public void aclarar ( ) { aniadir ( " aclarar ( ) " ) ; }// Probar la nueva clase:public static void main(String[] args) {Detergente x = new Detergente();x.diluir ( );x.aplicar ( );x.frotar ( );x.aclarar ( );x.escribir ( );System.out.println("Probando la clase base: " ) ;ProductoLimpieza.main(args); } }

Esto demuestra un gran nmero de aspectos. En primer lugar, en el mtodo aniadir( ) de la clase ProductoLimpieza, se concatenan Cadenas de caracteres a s utilizando el operador +=, que es uno de los operadores (junto con '+') que los diseadores de Java "sobrecargaron" para que funcionara con Cadenas de caracteres.Redefinicin de los miembros en las clases derivadas

Segundo, tanto ProductoLimpieza como Detergente contienen un mtodo main( ). Se puede crear un mtodo main( ) por cada clase que uno cree, y se recomienda codificar de esta forma, de manera que todo el cdigo de prueba est dentro de la clase. Incluso si se tienen muchas clases en un programa, slo se invocar al mtodo main( ) de la clase invocada en la lnea de comandos.Redefinicin de los miembros en las clases derivadas

(Dado que main( ) es pblico, no importa si la clase a la que pertenece es o no pblica.) Por tanto, en este caso, cuando se escriba java Detergente, se invocar a Detergente.main( ). Pero tambin se puede hacer que ProductoLimpieza invoque a ProductoLimpieza.main( ), incluso aunque ProductoLimpieza no sea una clase pblica.Redefinicin de los miembros en las clases derivadas

Esta tcnica de poner un mtodo main( ) en cada clase permite llevar a cabo pruebas para cada clase de manera sencilla. Y no es necesario eliminar el mtodo main( ) cuando se han acabado las pruebas; se puede dejar ah por si hubiera que usarlas para otras pruebas ms adelante.Redefinicin de los miembros en las clases derivadas

Aqu, se puede ver que Detergente.main( ) llama a ProductoLimpieza.main( ) explcitamente, pasndole los mismos argumentos de la lnea de comandos (sin embargo, se podra pasar cualquier array de Cadenas de caracteres).Es importante que todos los mtodos de ProductoLimpieza sean pblicos. Recuerde que si se deja sin poner cualquier modificador de miembro, el miembro ser por defecto "amistoso", lo cual permite acceder slo a los miembros del paquete. Por consiguiente, dentro de este paquete, cualquiera podra usar esos mtodos si no hubiera modificador de acceso. Detergente no tendra problemas, por ejemploRedefinicin de los miembros en las clases derivadas

Sin embargo, si se fuera a heredar desde ProductoLimpieza una clase de cualquier otro paquete, sta slo podra acceder a las clases pblicas. Por tanto, al planificar la herencia, como regla general, deben hacerse todos los campos privados y todos los miembros pblicos.Por supuesto, en los casos particulares hay que hacer ajustes, pero sta es una regla til.Redefinicin de los miembros en las clases derivadas

Fjese que ProductoLimpieza tiene un conjunto de mtodos en su interfaz: aniadir( ), diluir( ), aplicar(), frotar( ) y escribir( ). Dado que Detergente se hereda de ProductoLimpieza (mediante la palabra clave extends) automticamente se hace con estos mtodos en su interfaz, incluso aunque no se encuentren explcitamente definidos en Detergente. Se puede pensar que la herencia, por tanto, es una reutilizacin del interfaz. (La implementacin tambin se hereda, pero esto no es lo importante.)Redefinicin de los miembros en las clases derivadas

Como se ha visto en frotar( ), es posible tomar un mtodo que se haya definido en la clase base y modificarlo. En este caso, se podra desear llamar al mtodo desde la clase base dentro de la nueva versin. Pero dentro de frotar( ) no se puede simplemente invocar a frotar( ), dado que eso producira una llamada recursiva, que no es lo que se desea. Para solucionar este problema Java tiene la palabra clave super que hace referencia a la "superclase" de la cual ha heredado la clase actual.

Redefinicin de los miembros en las clases derivadas

Por consiguiente, la expresin super.frotar( ) llama a la versin que tiene la clase base del mtodo frotar( ).Redefinicin de los miembros en las clases derivadas

Al heredar, uno no se limita a usar los mtodos de la clase base. Tambin se pueden aadir nuevos mtodos a la clase derivada, exactamente de la misma manera que se introduce un mtodo en una clase: simplemente se definen. El mtodo aclarar( ) es un ejemplo de esta afirmacin.En Detergente.main( ) se puede ver que, para un objeto Detergente, se puede invocar a todos los mtodos disponibles, tambin en ProductoLimpieza y en Detergente (por ejemplo, aclarar( )).Redefinicin de los miembros en las clases derivadas