Documentos de Académico
Documentos de Profesional
Documentos de Cultura
POO:
DESARROLLO
DE CLASES
AVANZADA
1. Composición
Concepto
herencia
2. Herencia:
○ Conceptos Básicos
○ Constructores de clases derivadas
○ Herencia en Java: Clase OBJECT
○ Métodos heredados y sobreescritos
○ Clases y métodos final
○ Acceso a miembros derivados
○ Ejemplo
3. Poliformismo
4. Resumen modificadores
5. Clases abstractas
6. Interfaces
1.
COMPOSICIÓN
● La composición es el agrupamiento de uno o varios objetos y valores dentro de una clase.
● La composición crea una relación ‘tiene’ o ‘está compuesto por’.
● Por ejemplo, un rectángulo está compuesto por dos puntos (cada uno con sus coordenadas x,y).
CARACTERÍSTICAS COMUNES
COMPORTAMIENTOS COMUNES
profesor alumno
2. HERENCIA
➔ Composición :
Clase contenedora <<tiene-un>> Clase contenida
2.
◆ Herencia simple: una clase solo puede tener un padre, por lo tanto la estructura de clases será
en forma de árbol.
◆ Herencia múltiple: Una clase puede tener uno o varios padres. La estructura de clases es un
grafo. (*)No soportada en Java
2.
2. Extensión 3. Especificación
• Una clase puede servir para extender la •Una superclase puede servir para especificar la
funcionalidad de una superclase sin que funcionalidad mínima común de un conjunto
represente necesariamente un concepto de descendientes.
más específico.
2. HERENCIA
RECAPITULANDO
● ¿Cuándo crearemos una clase padre (base o superclase)? Principalmente bajo dos circunstancias:
1. Cuando caigamos en la cuenta de que diversos tipos (objetos) tienen algo en común. Pongamos
por ejemplo el juego del ajedrez: peones, alfiles, rey, reina, caballos y torres, son piezas del juego.
Crearíamos, por tanto, una clase padre y derivamos cada pieza individual a partir de dicha clase
base.
2. Cuando necesitemos ampliar la funcionalidad de un programa sin tener que modificar el
código existente.
● La POO nos permite crear tipos (objetos) a partir de una clase, la herencia nos permite extender esos
tipos sin necesidad de rescribir todo el código, únicamente escribimos las mejoras y lo demás se
hereda de la clase padre.
● Una regla que nos puede ayudar en el diseño de la jerarquía de herencia de clases en nuestros
programas de Java es la regla de “Es-un”. Si un objeto de la subclase “es-un” objeto de la
superclase, entonces el diseño sería correcto. Como hemos visto anteriormente.
2.
➔ El método toString lo tienen todos los objetos ya que se hereda de la clase Object. De la que
heredan todas las clases de manera implícita. Este método es el que se invoca al mostrar un
objeto por pantalla y por defecto muestra la clase del objeto y una referencia a dónde se
encuentra en memoria. Por ejemplo la clase String lo tiene sobrescrito para mostrar por pantalla
el String que contiene. En cualquier clase puedes sobrescribir este método para que al mostrar
un objeto por pantalla se muestre lo que tú quieras.
➔ También el método equals que hemos utilizado en la clase String es heredado de Object. Por
lo tanto sabemos que cualquiera de estos dos métodos lo va a tener cualquier objeto de
cualquier clase en Java.
2.
2.7 Ejemplo
➔ Vamos a crear un programa que tenga una clase
padre Persona, con los atributos: nombre, dirección,
dni y teléfono. De esta clase heredarán Alumno, que
además tendrá los atributos número de expediente,
nombre del ciclo, curso y un array de 5 notas (para
las notas de las asignaturas), y crearemos también
Profesor, que tendrá los siguientes atributos extra:
código de profesor, departamento al que pertenece,
horario (mañana o tarde) y un array con los
nombres de las asignaturas que imparte (máximo 5)
➔ Ver ejemplo en el aula virtual.
3. POLIMORFISMO
➔ Una misma llamada ejecuta distintas sentencias dependiendo de la clase a la que pertenezca el
objeto.
➔ Como se ha mencionado anteriormente en este mismo tema, hay una regla sencilla que nos
permite saber si la herencia es o no el diseño correcto para nuestros programas, para
nuestras clases.
➔ La regla “es-un” afirma que todo objeto de la subclase es un objeto de la superclase.
➔ Por ejemplo, imaginemos dos clases: Empleados y Jefes. En el caso de que una deba heredar de
otra ¿cuál sería el diseño de herencia correcto? ¿Debe heredar la clase Jefes de la clase
Empleados? ¿O debe ser al revés? En casos como este es donde debemos aplicar la regla “es-
un” para que el diseño de la herencia sea correcto.
➔ Aplicando dicha regla cabe decir que un Jefe “es-un” Empleado obligatoriamente. Sin embargo,
no podemos afirmar lo contrario: un Empleado no “es-un” Jefe obligatoriamente.
➔ Así que el diseño correcto debería ser que la clase Jefes herede de Empleados, o dicho de
otra forma, la clase Jefes debe ser subclase de Empleados o Empleados superclase de Jefes.
3.
➔ Otra manera de formular la regla “es-un” es el llamado principio de sustitución. Este afirma
que se puede utilizar un objeto del tipo de la subclase siempre que el programa espere un
objeto de la superclase. Por ejemplo, se puede asignar un objeto de subclase a una variable de
superclase.
➔ Jefes herede de Empleados, o dicho de otra forma, la clase Jefes debe ser subclase de
Empleados o Empleados superclase de Jefes.
➔ Otra manera de formular la regla “es-un” es el llamado principio de sustitución. Este afirma
que se puede utilizar un objeto del tipo de la subclase siempre que el programa espere un
objeto de la superclase. Por ejemplo, se puede asignar un objeto de subclase a una variable de
superclase.
3.
➔ En la imagen anterior vemos como por un lado tenemos un objeto de tipo Jefes llamado
“Juan” y por otro lado tenemos un Array de tipo Empleados llamado “losEmpleados”. Se puede
observar como se aplica el principio de sustitución asignando el objeto de tipo Jefes a la
variable de tipo Empleados. Este fenómeno es lo que se conoce como polimorfismo: una
variable de tipo Empleados puede referirse a un objeto de tipo Empleados o a cualquier objeto
de una subclase de Empleados (en este caso Jefes).
3.
Enlazado dinámico
➔ Como se observa en la imagen anterior, tanto la clase Empleados como la
subclase Jefes tienen un método llamado getSueldo(). También vemos
como tenemos un objeto llamado “obj” que es de tipo Empleados. La
pregunta que surge es: ¿a cuál de los dos métodos getSueldo llama el
objeto “obj” a cada vuelta de bucle for-each? Lo normal sería pensar que
llama el método getSueldo() de la clase Empleados. Sin embargo, dentro
del bucle for-each el enlazado dinámico entra en acción debido a la
naturaleza polimórfica del objeto “obj”. A cada vuelta de bucle el objeto
“obj” se comportará de diferente forma, unas veces como Empleados y
otra como Jefes dando lugar al enlazado dinámico proceso por el cual en
ocasiones llamará al método getSueldo() de la clase Empleados y en
otras ocasiones al método getSueldo() de la clase Jefes, dependiendo
dela forma que tome obj.
3.
CASTING DE OBJETOS
public class UsoEmpleadosCAST {
public static void main(String[] args) {
JefesCAST lola= new JefesCAST("LOLA",3900, 2012, 04,29);
EmpleadosCAST [] losEmpleados= new EmpleadosCAST[6]; losEmpleados[0]= new
EmpleadosCAST("Juan", 2700, 2021, 10,02);
losEmpleados[1]= new EmpleadosCAST("Pepe", 1500, 2024, 12,03);
losEmpleados[2]= new EmpleadosCAST("Ana", 2500, 2022, 9,04);
losEmpleados[3]= new EmpleadosCAST("Eva", 1700, 2023, 8,05); losEmpleados[4]=
lola;// principio de sustitución ES UN
EmpleadosCAST lolaAdmin= lola; //UPcasting (casting implícito) una variable de tipo jefe la estamos guardando en una variable de tipo empleado que es la
clase padre!!
//¿Qué pasa si lo hacemos al revés?
//EmpleadosCAST lolo= new EmpleadosCAST("LOLO", 1500, 2024, 12,03);
//JefesCAST loloDirector= lolo; //no se puede convertir empleados a jefes y esto es porque no se cumple el principio de sustitución ES UN
// a veces, a la hora de programar es necesario hacer un DOWNCasting o casting explícito
// pensais que funcionaria si hacemos lo siguiente??
// JefesCAST loloDirector= (JefesCAST)lolo; //no da error de compilación
/*¿cómo lo solucionamos?-> haciendo de forma correcta el principio de sustitución
* si lolo va a ser jefe y un jefe ES UN siempre empleado podremos
* hacer la siguiente declaración y después castear
*/
3.
CASTING DE OBJETOS
EmpleadosCAST lolo= new JefesCAST("LOLO", 1500, 2024, 12,03); //puedo instanciar un objeto de tipo jefe en
// una variable de tipo Empleado
JefesCAST loloDirector= (JefesCAST)lolo; //DownCasting
//¿Para que lo vamos a usar?
//ejem: añadir una posición más al array para ver el ejemplo
//losEmpleados[5]. //no agarra el método setIncentivo de jefes porque el array es de tipo empleado
//Solución?? DownCasting
arturo.setIncetivo(111);
}
4. RESUMEN DE MODIFICADORES
El sentido último de crear clases abstractas y métodos abstractos, es marcar la pauta a seguir e
5. CLASES
Añade comentarios
ampliando las
explicaciones
5. CLASES ABSTRACTAS
5. CLASES ABSTRACTAS
5. CLASES ABSTRACTAS
Recapitulando:
● Imaginemos un escenario en el que no tenga sentido
● Una clase abstracta puede contener tanto
crear cierto tipo de objetos de una clase o se quiere
métodos abstractos (sin implementar)
evitar su creación, pero la clase es útil para
como no abstractos (implementados).
generalizar miembros de otras clases que heredan de
Pero al menos uno debe ser abstracto.
ella. En este caso nos interesará declarar esa clase
como Clase Abstracta. ● Para declarar una clase o método como
abstracto se utiliza el modificador
● Una clase abstracta es una clase que declara abstract.
la existencia de algunos métodos pero no su ● Una clase abstracta no se puede
implementación (es decir, contiene la cabecera instanciar, pero sí heredar.
del método pero no su código). Los métodos sin ● Las subclases tendrán que implementar
implementar son métodos abstractos. obligatoriamente el código de los
métodos abstractos (a no ser que
también se declaren como abstractas).
5. CLASES
Recapitulando:
● Una clase abstracta según hemos dicho no puede instanciarse, por lo que no tiene sentido
que tenga constructores.
● Una clase abstracta sí puede tener herencia.
● Una clase abstracta puede tener atributos y métodos.
● Los métodos de una clase abstracta pueden ser abstractos o normales. Método abstracto es
aquel que no tiene cuerpo.
● Para que una clase se declare como abstracta tenemos que usar la palabra clave abstrac
● Las clases que heredan de una clase abstract tienen la obligación de implementar los métodos
abstractos de la misma.
● Si la clases hija no queremos que implemente este método, la misma también debería ser
abstract.
● Un método abstract no puede ser static.
5. CLASES
5. CLASES