Vous êtes sur la page 1sur 8

3.2 Clasificacin. Herencia simple, herencia mltiple.

Herencia La herencia es un mecanismo que permite la definicin de una clase a partir de la definicin de otra ya existente. La herencia permite compartir automticamente mtodos y datos entre clases, subclases y objetos. La herencia est fuertemente ligada a la reutilizacin del cdigo en la OOP. Esto es, el cdigo de cualquiera de las clases puede ser utilizado sin ms que crear una clase derivada de ella, o bien una subclase. Hay dos tipos de herencia: Herencia Simple y Herencia Mltiple. La primera indica que se pueden definir nuevas clases solamente a partir de una clase inicial mientras que la segunda indica que se pueden definir nuevas clases a partir de dos o ms clases iniciales. Java slo permite herencia simple.

Existe la herencia mltiple en Java? Por qu?


Objetivo: fortalecer los conceptos de clases, mtodos, propiedades o atributos, herencia, constructores y acerca de los mtodos Get y Set. Todo esto con ayuda del programa realizado en la gua anterior con nuestro Silabario para programadores. El trabajo estructurado de la semana pasada ahora lo traslademos a una aplicacin, siempre en el ambiente consola, en la cual definamos con un alto grado de encapsulamiento, las clases que harn posible la realizacin de la aplicacin y llevarn definida todo el funcionamiento, o lo que es mismo, la capa de negocios del programa. El ejemplo es sencillo. El Silabario lo que realiza es una serie de operaciones bsicas que resuelven 4 tipos de problemas distintos: El factorial de nmero, la tabla de multiplicar de un nmero, la clasificacin de la edad del usuario y la eleccin de la estacin del ao favorita del usuario. El silabario adems, tiene la caracterstica que el programador escoger la sentencia o instruccin bsica que brinde la solucin ms sencilla y ptima para cada uno de los problemas. Para efectos de esta prctica, y porque creo que es la mejor manera de poder apreciar las clases y objetos de este ejercicio, definiremos cada clase como una clase Operacin, que es la que facilitar y tendr las herramientas necesarias para efectuar la resolucin de cada uno de los problemas. Un objeto operacin necesita de propiedades o atributos. Una operacin necesita de operadores, uno, dos ms. Es por eso que definiremos dos atributos para realizar dichas operaciones. Con dos bastarn para este ejercicio. Los mtodos de esta clase son muy variados. Cada una de las operaciones realizar uno diferente, por lo tanto no cabe dentro de la percepcin de un objeto Operacin bsico, la definicin de cada uno de los mtodos. Los mtodos que s se necesitaran son los populares mtodos GET y SET, que nos sirven para leer y cambiar los valores de una propiedad especfica. Como hemos definido propiedades, stas necesitan de sus getters y setters. La clase de una Operacin Bsica para el silabario quedar as: public class operacionBase { protected int operador; public operacionBase(){ this.operador=0; } public void setOperador(int o){ this.operador=o;

} public int getOperador(){ return this.operador; } } Declaramos la propiedad con visibilidad protected por motivos de seguridad, para que solamente los miembros de esa clase y los que heredan de ella, es decir las subclases, puedan accesar a estos atributos. Como hemos definido ya una clase base, ahora podremos definir el resto de clases que podrn heredar de la clase base. Cabe destacar que no siempre se podr hacer una clase base y con respecto a esta empezar a heredarles a otras. Esto depende de la naturaleza de cada aplicacin, y de la manera de cmo el programador disee su capa de negocios. Para realizar la clase que nos devuelva el factorial de un nmero, el programador puede escoger la instruccin While. Por lo tanto el programador debe desarrollar el mtodo que reciba como parmetro el nmero del que se desee el factorial y que devuelva el resultado esperado. Heredando de la clase base, tenemos ya garantizados los atributos y mtodos propios de la misma, por lo tanto, la clase para realizar el factorial del nmero podra quedar as: public class operacionFactorial extends operacionBase{ public operacionFactorial(){ super(); } public int devolverFactorial(){ int factorial=1; int cont=1; while (cont <= this.operador) { factorial *= cont; cont++; } return factorial; } } El diagrama UML nos ayudar a comprender mejor la herencia y estructura de estas clases:

Como puede observar el programador, se utiliza la propiedad operador cuya definicin pertenece a la clase base. Sin

embargo, como la clase operacionFactorial hereda todos los atributos y mtodos de la clase bsica, podemos hacer un llamado a dicha propiedad con la ayuda de la sentencia this.

3.3 Reutilizacin de miembros heredados.

La reutilizacin de cdigo se refiere al comportamiento y a las tcnicas que garantizan que una parte o la totalidad de un programa informtico existente se pueda emplear en la construccin de otro programa. De esta forma se aprovecha el trabajo anterior, se economiza tiempo, y se reduce la redundancia. La manera ms fcil de reutilizar cdigo es copiarlo total o parcialmente desde el programa antiguo al programa en desarrollo. Pero es trabajoso mantener mltiples copias del mismo cdigo, por lo que en general se elimina la redundancia dejando el cdigo reusable en un nico lugar, y llamndolo desde los diferentes programas. Este proceso se conoce como abstraccin. La abstraccin puede verse claramente en las bibliotecas de software, en las que se agrupan varias operaciones comunes a cierto dominio para facilitar el desarrollo de programas nuevos. Hay bibliotecas para convertir informacin entre diferentes formatos conocidos, acceder a dispositivos de almacenamiento externos, proporcionar una interfaz con otros programas, manipular informacin de manera conocida (como nmeros, fechas, o cadenas de texto). Para que el cdigo existente se pueda reutilizar, debe definir alguna forma de comunicacin o interfaz. Esto se puede dar por llamadas a una subrutina, a un objeto, o a una clase. Como se ha comentado anteriormente la clase descendiente puede aadir sus propios atributos y mtodos pero tambin puede sustituir u ocultar los heredados. En concreto: 1. Se puede declarar un nuevo atributo con el mismo identificador que uno heredado, quedando este atributo oculto. Esta tcnica no es recomendable. 2. Se puede declarar un nuevo mtodo de instancia con la misma cabecera que el de la clase ascendiente, lo que supone su sobreescritura. Por lo tanto, la sobreescritura o redefinicin consiste en que mtodos adicionales declarados en la clase descendiente con el mismo nombre, tipo de dato devuelto y nmero y tipo de parmetros sustituyen a los heredados. 3. Se puede declarar un nuevo mtodo de clase con la misma cabecera que el de la clase ascendiente, lo que hace que ste quede oculto. Por lo tanto, los mtodos de clase o estticos (declarados como static) no pueden ser redefinidos. 4. Un mtodo declarado con el modificador final tampoco puede ser redefinido por una clase derivada. 5. Se puede declarar un constructor de la subclase que llame al de la superclase de forma implcita o de mediante la palabra reservada super. 6. En general puede accederse a los mtodos de la clase ascendiente que han sido redefinidos empleando la palabra reservada super delante del identificador del mtodo. Este mecanismo slo permite acceder al metodo perteneciente a la clase en el nivel inmediatamente superior de la jerarqua de clases.
Practicas: Construyamos la clase Taxista.java con el siguiente cdigo: public class Taxista extends Persona { private int nLicencia; public void setNLicencia(int num) {

nLicencia = num; } public int getLicencia() { return nLicencia; } } Y construyamos ArranqueTaxista.java: public class ArranqueTaxista { public static void main (String arg[]){ Taxista tax1 = new Taxista(); tax1.setNombre("Luis"); tax1.setEdad(50); System.out.println( tax1.getNombre()); System.out.println(tax1.getEdad()); } } Ahora intentemos usar el constructor que exista en la clase Persona que recibia el nombre de la persona y vamos a usarlo para la clase Taxista. Para ello construyamos la clase ArranqueTaxista2.java: public class ArranqueTaxista2 { public static void main (String arg[]){ Taxista tax1 = new Taxista("Jose"); tax1.setEdad(50); System.out.println( tax1.getNombre()); System.out.println(tax1.getEdad()); System.out.println(tax1.getNLicencia()); } } Se genera un error de compilacin, debido a que los constructores no se heredan, sino que hay que definir nuestros propios constructores. Agreguemos en la clase Taxista los siguientes constructores:

public Taxista(int licencia) { super(); nLicencia = licencia; } public Taxista(String nombre,int licencia) { super(nombre); nLicencia = licencia; } Ahora si podremos compilar y ejecutar la clase ArranqueTaxista2. La llamada al mtodo super indica que estamos llamando a un constructor de la clase base (pensemos que un Taxista antes que Taxista es Persona y por tanto tiene sentido llamar al constructor de Persona antes que al de Taxista). Adems gracias al nmero de parmetros de la llamada a super podemos especificar cul de los constructores de la clase base queremos llamar. En java se pueden emplear dos palabras clave: this y super . Como vimos en la introduccin a la programacin orientada a objetos, this hace alusin a todo el objeto y super hace alusin a la parte heredada, por ello empleamos super para referenciar al constructor de la clase base. Practicas: Ahora vamos a agregar la funcin getNombre dentro de la clase Taxista, es decir, tenemos la misma funcin en Persona y en Taxista: public String getNombre() { return "Soy un taxista y me llamo: " + super.getNombre(); } Compilamos Taxista y ejecutamos ArranqueTaxista2. Veremos que el mensaje que aparece en pantalla demuestra que la funcin getNombre llamada es la de del tipo real del objeto construido, en este caso la de la clase derivada que es Taxista. Tambien apreciamos que para acceder al atributo nombre es necesario acceder al mtodo getNombre de la clase base (y por ello emplear super).

En java los atributos y mtodos de la clase base pueden cambiar su modificador de visibilidad dentro de la clase derivada, la siguiente tabla recoge dichos cambios: Modificadores en la clase base public private protected paquete En la clase derivada se transforman en public inaccesible protected paquete Inaccesible significa que, a pesar de haber sido heredado, no hay permisos en la clase derivada para poder acceder a dicho elemento inaccesible, pero an as, se pueden llamar a mtodos de la clase base que si pueden acceder y modificar al elemento. Recordemos que protected significa que es private, pero que al heredar no se hace inaccesible, es decir que desde la clase derivada se puede acceder.

3.4 Referencia al objeto de la clase base

La jerarqua de clases que describen las figuras planas


figura: Figura.java, FiguraApp.java Consideremos las figuras planas cerradas como el rectngulo, y el crculo. Tales figuras comparten caractersticas comunes como es la posicin de la figura, de su centro, y el rea de la figura, aunque el procedimiento para calcular dicha rea sea completamente distinto. Podemos por tanto, disear una jerarqua de clases, tal que la clase base denominada Figura, tenga las caractersticas comunes y cada clase derivada las especficas. La relacin jerrquica se muestra en la figura

La clase Figura es la que contiene las caractersticas comunes a dichas figuras concretas por tanto, no tiene forma ni tiene rea. Esto lo expresamos declarando Figura como una clase abstracta, declarando la funcin miembro area abstract. Las clases abstractas solamente se pueden usar como clases base para otras clases. No se pueden crear objetos pertenecientes a una clase abstracta. Sin embargo, se pueden declarar variables de dichas clases. En el juego del ajedrez podemos definir una clase base denominada Pieza, con las caractersticas comunes a todas las piezas, como es su posicin en el tablero, y derivar de ella las caractersticas especficas de cada pieza particular. As pues, la clase Pieza ser una clase abstracta con una funcin abstract denominada mover, y cada tipo de pieza definir dicha funcin de acuerdo a las reglas de su movimiento sobre el tablero.

La clase Figura

La definicin de la clase abstracta Figura, contiene la posicin x e y de la figura particular, de su centro, y la funcin area, que se va a definir en las clases derivadas para calcular el rea de cada figura en particular.
public abstract class Figura { protected int x; protected int y; public Figura(int x, int y) { this.x=x; this.y=y; } public abstract double area(); }

La clase Rectangulo

Las clases derivadas heredan los miembros dato x e y de la clase base, y definen la funcin area, declarada abstract en la clase base Figura, ya que cada figura particular tiene una frmula distinta para calcular su rea. Por ejemplo, la clase derivada Rectangulo, tiene como datos, aparte de su posicin (x, y) en el plano, sus dimensiones, es decir, su anchura ancho y altura alto.
class Rectangulo extends Figura{ protected double ancho, alto; public Rectangulo(int x, int y, double ancho, double alto){ super(x,y); this.ancho=ancho; this.alto=alto; } public double area(){ return ancho*alto; } }

La primera sentencia en el constructor de la clase derivada es una llamada al constructor de la clase base, para ello se emplea la palabra reservada super. El constructor de la clase derivada llama al constructor de la clase base y le pasa las coordenadas del punto x e y. Despus inicializa sus miembros dato ancho y alto. En la definicin de la funcin area, se calcula el rea del rectngulo como producto de la anchura por la altura, y se devuelve el resultado

La clase Circulo

class Circulo extends Figura{ protected double radio; public Circulo(int x, int y, double radio){ super(x,y); this.radio=radio; } public double area(){ return Math.PI*radio*radio; } }

Como vemos, la primera sentencia en el constructor de la clase derivada es una llamada al constructor de la clase base empleando la palabara reservada super. Posteriormente, se inicializa el miembro dato radio, de la clase derivada Circulo. En la definicin de la funcin area, se calcula el rea del crculo mediante la conocida frmula r2, o bien *r*r. La constante Math.PI es una aproximacin decimal del nmero irracional .

Uso de la jerarqua de clases


Creamos un objeto c de la clase Circulo situado en el punto (0, 0) y de 5.5 unidades de radio. Calculamos y mostramos el valor de su rea.
Circulo c=new Circulo(0, 0, 5.5); System.out.println("Area del crculo "+c.area());

Creamos un objeto r de la clase Rectangulo situado en el punto (0, 0) y de dimensiones 5.5 de anchura y 2 unidades de largo. Calculamos y mostramos el valor de su rea.
Rectangulo r=new Rectangulo(0, 0, 5.5, 2.0); System.out.println("Area del rectngulo "+r.area());

Veamos ahora, una forma alternativa, guardamos el valor devuelto por new al crear objetos de las clases derivadas en una variable f del tipo Figura (clase base).
Figura f=new Circulo(0, 0, 5.5); System.out.println("Area del crculo "+f.area()); f=new Rectangulo(0, 0, 5.5, 2.0); System.out.println("Area del rectngulo "+f.area());

Vous aimerez peut-être aussi