Está en la página 1de 47

Tema 11. Programación orientada a objetos: Herencia.

Curso 2018/2019

Tema 11. Programación orientada a objetos: HERENCIA

1. Introducción
Finalidad
Superclase y subclase
Especialización && Generalización
Superclase directa e indirecta
Tipo de relación

2 Superclases y subclases

2.1 Tratamiento de los objetos de una relación de herencia


2.2 Sobrescribir métodos

3 Miembros (atributos o métodos) protected.

4 Práctica de herencia: relación entre las superclases y las subclases.

4.1 Creación y uso de una clase EmpleadoPorComision


4.2 Creación de una clase EmpleadoBaseMasComision sin usar la herencia.
4.3 Creación de una jerarquía de herencia: EmpleadoPorComision –
EmpleadoBaseMasComision.
4.4 La jerarquía de herencia EmpleadoPorComision - EmpleadoBaseMasComision
mediante el uso de variables de instancia protected
4,5 La jerarquía de herencia EmpleadoPorComision - EmpleadoBaseMasComision
mediante el uso de variables de instancia private.

5 Ingeniería de software mediante la herencia

6 La clase Object

7 Los constructores en las subclases

1-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

1. Introducción

Finalidad

La herencia es una forma de reutilización de software en la que se crea una nueva


clase absorbiendo los miembros de una clase existente, y se mejoran con nuevas
capacidades, o con modificaciones en las capacidades ya existentes.

Con la herencia, los programadores ahorran tiempo durante el desarrollo, al reutilizar


software probado y depurado.

Los lenguajes de programación orientados a objetos nos proporcionan, a parte de naturalidad


al escribir código, la reutilización del mismo; de ahí que una de las principales
ventajas de la POO sea el concepto de herencia.

2-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Superclase y subclase
Al crear una clase, en vez de declarar miembros (atributos y métodos) completamente nuevos, el
programador puede designar que la nueva clase herede los miembros de una clase existente.

La clase existente se conoce como superclase, y la nueva clase se conoce como subclase.

Aaa SUPERCLASE
clase de la que se hereda

SUBCLASE
clase que hereda Bbb

Clase Aaa:SUPERCLASE Clase Bbb:SUBCLASE

public class Aaa { public class Bbb extends Aaa {

… …
} }

3-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Cada subclase puede convertirse en la superclase de futuras subclases.

La clase Triangulo es subclase de la


clase Poligono y superclase de las
clases Equilatero, Isosceles y
Escaleno.

La implementación de la herencia se realiza mediante la palabra reservada: extends.

Sintaxis:

modificador_acceso class nom_clase extends nom_clase {

Ejemplo:

public class Poligono {

public class Circulo extends Poligono {

public class Rectangulo extends Poligono {

public class Triangulo extends Poligono {

4-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Otro ejemplo:

5-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Especialización && Generalización

Una subclase generalmente agrega sus propios atributos y métodos, además de los atributos
y/o métodos heredados.

Una subclase es más específica que su superclase y representa a un grupo más


especializado de objetos. La subclase hereda los comportamientos de su superclase y tiene
también, generalmente, comportamientos adicionales (específicos de la subclase). Es por ello
que a la herencia se le conoce algunas veces como especialización.

Las clases se disponen en una jerarquía (jerarquía de clases), donde una clase hereda los
atributos y operaciones de las clases superiores en la jerarquía.

Ejemplo de herencia: En nuestro mundo real, estamos modelizando a los animales.


Todos ellos, deben de hacerRuido, comer, dormir y rugir. Cada una de las especializaciones,
tanto los Felinos como los Caninos saben como rugir. A su vez, cada una de las
especializaciones saben como comer, y como hacerRuido. Todos ellos, realizan la operación
de dormir de la misma manera que se ha determinado en la clase Animal.

La Herencia representa, muchas veces, relaciones de generalización / especialización


entre clases.

6-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Superclase directa e indirecta

La superclase directa es la superclase a partir de la cual la subclase hereda en forma


explícita. Una superclase indirecta es cualquier clase arriba de la superclase directa en la
jerarquía de clases.

En Java, la jerarquía de clases empieza con la clase Object (en el paquete java.lang), a partir
de la cual se extienden (o “heredan”) todas las clases en Java, ya sea en forma directa o
indirecta.

7-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Tipo de relación: es un

Aunque en la POO existen diversos tipos de herencia, para simplificar diremos que cuando una clase
hereda de otra, lo que está expresando es una relación "es un".

Por ejemplo si la clase Perro hereda de la clase Mamifero significará que Perro es un Mamifero, es
decir, todo lo que haga un Mamifero lo podrá hacer también Perro.

La clase Oveja y Tigre hereda también de la clase Mamifero, un objeto del tipo Oveja, Tigre o Perro
tiene atributos y métodos comunes que hereda de la clase Mamifero.

Cualquier objeto instanciado de la clase Perro, Tigre u Oveja “es un” objeto de la clase Mamifero.

Es necesario hacer una diferencia entre la relación “es un” y la relación “tiene un”.

La relación “es un” representa a la herencia. En este tipo de relación, un objeto de


una subclase puede tratarse también como un objeto de su superclase.

Por ejemplo, un automóvil es un vehículo.

vehiculo

automovil

automóvil es un vehículo

8-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

La relación “tiene un” identifica a la composición. En este tipo de relación, un


objeto contiene referencias a objetos como atributos.

Por ejemplo, un automóvil tiene un volante.

automovil volante

automóvil tiene un volante

No todas las relaciones (dependencias) de clases son una relación de herencia o


composición. Existen otras relaciones: asociación, agregación, ...

Las organizaciones y empresas desarrollan sus propias bibliotecas de clases y pueden


aprovechar las que ya están disponibles.

9-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

2 Superclases y subclases

Las relaciones de herencia forman estructuras jerárquicas en forma de árbol (Jerarquía de


clases).

MiembroIES

Empleado Estudiante ExAlumno

Docente Administrativo

Administrador Profesor

Cada flecha (línea) representa una relación “es un”. Por ejemplo, al seguir las flechas en esta
jerarquía de clases podemos decir “un Empleado es un MiembroIES” y “un Profesor es un
miembro Docente”.

MiembroIES es la superclase directa de Empleado, Estudiante y Exalumno, y es una


superclase indirecta de todas las demás clases en el diagrama.

Si comienza desde la parte inferior del diagrama, podrá seguir las flechas y aplicar la relación
es-un hasta la superclase superior. Por ejemplo, un Administrador es un miembro Docente,
es un Empleado y es un MiembroIES.

10-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

2.1 Tratamiento de los objetos de una relación de herencia

Tratamiento de los objetos de clases con relaciones de herencia:

1. Los objetos de las subclases pueden tratarse como objetos de la superclase.


UpCasting

2. Los objetos de una superclase no pueden tratarse como objetos de sus


subclases. DownCasting

1- Los objetos de las subclases pueden tratarse como objetos de la superclase.

Ejemplos

Un Docente es un Empleado.

Docente d = new Docente();


Empleado e1 = d;
// se ha producido una conversión(casting) automática de tipo UpCasting
// La conversión no modifica el objeto, solo su tipo

Un Administrador y un Profesor son Docente

Docente d1, d2 ;
Administrador a = new Administrador();
Profesor pro = new Profesor();
d1 = a;
d2 = pro;

o también directamente

Docente d1= new Administrador();


Docente d2= new Profesor();

Un Profesor es un MiembroIES

MiembroIES m= new Profesor();

Conclusión: cualquier referencia a un objeto de una subclase se puede guardar en una


variable de la superclase.

11-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

2- Los objetos de una superclase no pueden tratarse como objetos de sus subclases.

Un Empleado no siempre es un Docente.

Empleado e = new Empleado();


Docente d = new Docente();

Docente d2 = e; // error no es posible tratar al Empleado como un Docente


// ya que Docente tiene capacidades de las que carece Empleado

// Si utilizamos el operador de conversión ?

Depende de la instancia de e

Docente d3= (Docente) e; //Se produce el error, e no es un docente.

// no se produce error, e es un docente

e=d;

d3= (Docente) e; // conversión DownCasting correcta, e es un docente

En conclusión
Cada objeto de una subclase es también un objeto de la superclase. Sin embargo,
el objeto de una superclase no es un objeto de las subclases.

DownCasting, sólo se realiza correctamente cuando la superclase es una


referencia a un objeto de la subclase

12-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

2.2 Sobrescribir métodos

Las subclases pueden sobrescribir los métodos de la superclase.

A pesar de que una subclase puede utilizar un método de superclase (por herencia), a
menudo esa subclase requiere una versión personalizada del método. En dichos casos, la
subclase puede sobrescribir (redefinir) el método de la superclase con una
implementación más apropiada.

En el tema anterior vimos como todas las clases heredan los métodos toString() y equals(), y
como se implementaron (sobrescribieron) dicho métodos.

Ejemplo de método sobrescrito

Importante tener en cuenta que, sobrecargar un método es un concepto distinto a sobrescribir


un método. La sobrecarga de un método significa tener varias implementaciones del mismo
método con parámetros distintos. Para sobrescribir un método hay que respetar totalmente la
declaración del método (parámetros y retorno).

Cuando un método de la subclase sobrescribe al método de la superclase, éste último (el


método de la superclase) puede utilizarse desde la subclase si se antepone a su nombre la
palabra clave super y un punto (.)

La palabra reservada super es una referencia al objeto actual pero apuntando al padre, se
utiliza para acceder desde un objeto a atributos y métodos (incluyendo constructores) del
padre.

Cuando el atributo o método al que accedemos no ha sido sobrescrito en la subclase, el uso


de super es redundante.

Tenemos que tener en cuenta, de forma general, que al ejecutar un método, se busca
su implementación de abajo hacia arriba en la jerarquía de clases.

13-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

14-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

En la jerarquía de clases de la figura la clase Lobo hereda directamente de la clase Canino, y


la clase Canino hereda de la clase Animal.

Como ya se ha dicho, por herencia un Lobo es un Animal, un objeto de tipo Lobo se pude
tratar como un objeto de tipo Animal.

Animal animal =new Lobo();

15-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

3 Miembros (atributos o métodos) protected.

Hasta ahora habíamos dicho que una clase no tiene acceso a los atributos de otra clase de
acuerdo con el principio de ocultación de la información, por lo tanto una subclase no
debería tener acceso a los campos de una superclase de acuerdo a este principio . Sin
embargo, esto podría considerarse como demasiado restrictivo para una subclase, porque
limita el acceso a una subclase como si se tratara de una clase cualquiera, cuando en
realidad la relación de una superclase con una subclase es más estrecha que con una clase
externa.

En diferentes lenguajes, Java entre ellos, se usa un nivel de acceso intermedio que no es ni
public ni private, sino algo intermedio que se denomina como “acceso protegido”, expresado
con la palabra clave protected, que significa que las subclases sí pueden tener acceso al
atributo o método.

El modificador de acceso protected puede aplicarse a todos los miembros de una clase:
atributos, métodos o constructores.

El modificador de acceso protected puede aplicarse a todos los miembros de una clase, es
decir, tanto a campos como a métodos o constructores. En el caso de métodos o
constructores protegidos, estos serán visibles/utilizables por las subclases y otras clases del
mismo paquete (package). El acceso protegido suele aplicarse a métodos o constructores,
pero preferiblemente no a campos, para evitar debilitar el encapsulamiento.

El delimitador de acceso protected suele usarse cuando se trabaja con herencia. Desde un
objeto de una subclase podremos acceder o invocar un campo o método declarado como
protected, pero no podemos acceder o invocar a campos o métodos privados de una
superclase.

Los modificadores de acceso public, private o protected.

16-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Los atributos o métodos declarados como Public son accesibles tanto desde fuera como
desde dentro de la clase.

Los atributos o métodos declarados como Private son accesibles sólo desde la misma clase
donde fueron definidos.

Ejemplo 0. La clase Interino define dos campos uno con un modificador de acceso protected
y otro private. En el programa test se crea un objeto de la clase y trata de acceder a ese
campo con una invocación directa del tipo interino1.idProfesor = “54-DY-87”.

public class Interino {


protected String idProfesor;
private String nombre;
//método toString
public String toString(){
return String.format( "Nombre:%s Id: %s", nombre, idProfesor);
}
}

public class TestInterino {

public static void main(String[] args) {


Interino interino1= new Interino();
interino1.idProfesor="54-DY-87";
interino1.nombre = "Pepe"; //Error
System.out.println(interino1.toString());
}
}

17-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Java admite una variante más en cuanto a modificadores de acceso: la omisión del mismo
(no declarar ninguno de los modificadores). En la siguiente tabla puedes comparar los efectos
de usar uno u otro tipo de declaración en cuanto a visibilidad de los campos o métodos:

MODIFICADOR CLASE PACKAGE SUBCLASE TODOS

public Sí Sí Sí Sí

protected Sí Sí Sí No

No especificado Sí Sí No No

private Sí No No No

Observación de ingeniería de software:

Como recomendación general los atributos deben ser private y los métodos
protected y/o public.

De acuerdo con lo anterior, los métodos de una subclase no pueden tener acceso
directo a los miembros private de su superclase. Una subclase puede modificar el
estado de las variables de instancia private de la superclase sólo a través de los
métodos que no sean private, que se proporcionan en la superclase y son
heredados por la subclase.

18-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

4. Práctica de herencia: relación entre las superclases y las subclases.

Todas las clases en Java (excepto Object) extienden (heredan) de una clase existente.

De hecho, cada clase en Java hereda en forma directa o indirecta los métodos de Object; la
clase Object no tiene atributos.

Si una clase no especifica que hereda de otra clase, la nueva clase hereda de Object en
forma implícita. En general, cuando se define una nueva clase que no hereda de otra no se
suele especificar en su código (de forma, implícita) “extends Object”.

Los ejemplos de esta sección están diseñados cuidadosamente para enseñar las
capacidades y ventajas de la herencia, utilizar miembros protected de la superclase y
cómo sobrescribir los métodos de la superclase para proporcionar versiones más apropiadas.
En definitiva, técnicas de ingeniería de software para crear clases que sean fáciles de
mantener, modificar y depurar, utilizando la herencia como una forma de reutilizar código.

Esta sección se va a ilustrar con ejemplos de una jerarquía de herencia que contiene dos
tipos de empleados (según salario) de una supuesta empresa:

- Empleados por comisión (EmpleadoPorComision), cobra un porcentaje de sus


ventas.

- Empleados por comisión con salario base (EmpleadoBaseMasComision) reciben


un salario base, más un porcentaje de sus ventas.

Desarrollamos 5 supuestos (ejemplos) de relación entre los empleados por comisión y los
empleados por comisión con salario base:

1º Creación y uso de una clase EmpleadoPorComision .

Declara la clase EmpleadoPorComision, la cual hereda directamente de la clase


Object.

2º Creación de una clase EmpleadoBaseMasComision sin usar la herencia.

El segundo ejemplo declara la clase EmpleadoBaseMasComision, la cual también


hereda directamente de la clase Object. Para crear esta clase escribimos todo el
código que requiera; veremos (en el tercer supuesto) que es mucho más eficiente
crear esta clase haciendo que herede de la clase EmpleadoPorComision.

19-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

3º Creación de una jerarquía de herencia:

EmpleadoPorComision

EmpleadoBasePorComision2

El tercer ejemplo declara una clase EmpleadoBaseMasComision2, la cual hereda


de la clase EmpleadoPorComision, los atributos se definen como private.

EmpleadoBasePorComision2 se trata de acceder a los miembros private de la


clase EmpleadoPorComision; esto produce errores de compilación, ya que la
subclase no puede acceder a las variables de instancia private de la superclase.

4º La jerarquía de herencia EmpleadoPorComision - EmpleadoBaseMasComision


mediante el uso de variables de instancia protected.

EmpleadoPorComision2

EmpleadoBasePorComision3

El cuarto ejemplo muestra que si las variables de instancia de


EmpleadoPorComision2 se declaran como protected, una clase
EmpleadoBaseMasComision3 que extiende a la clase EmpleadoPorComision2
puede acceder a los datos de manera directa.

20-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

5º La jerarquía de herencia EmpleadoPorComision - EmpleadoBaseMasComision


mediante el uso de variables de instancia private.

EmpleadoPorComision3

EmpleadoBaseMasComision4

El quinto ejemplo, establece las variables de instancia de EmpleadoPorComision a


private en la clase EmpleadoPorComision3, para hacer cumplir las
recomendaciones de ocultamiento.

EmpleadoBaseMasComision4 extiende a la clase EmpleadoPorComision3, utiliza


los métodos public de EmpleadoPorComision3 para manipular las variables de
instancia private.

Cada supuesto se va a desorrallar en un paquete, conservando así, al hacer el nuevo


supuesto, las clases definidas en los supuestos anteriores:

paquete clases
ejemplo1 EmpleadoPorComision
ejemplo2 EmpleadoBaseMasComision
ejemplo3 EmpleadoPorComision
EmpleadoBaseMasComision2
ejemplo4 EmpleadoBaseMasComision2
EmpleadoBaseMasComision3
Ejemplo5 EmpleadoPorComision2
EmpleadoBaseMasComision4

21-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

4.1 Ejemplo 1: creación y uso de una clase EmpleadoPorComision

Clase EmpleadoPorComision.

EmpleadoPorComision hereda de la clase Object (del paquete java.lang):

public class EmpleadoPorComision extends Object {

…...

Como la clase EmpleadoPorComision extiende la clase Object, la clase


EmpleadoPorComision hereda los métodos de la clase Object.

La clase EmpleadoPorComision declara las siguientes variables de instancia private:

String primerNombre
String apellidoPaterno
Stirng numeroSeguridadSocial
doble ventasBrutas // monto de ventas (es decir, total)
double tarifaComision // porcentaje de comisión

Declara los siguientes métodos:

* Un constructor ( con cinco argumentos). La integridad de los atributos


ventasBrutas y tarifaComision hace que se invoquen desde el constructor los
métodos establecer de ambos atributos.

* Un método establecer (set) por cada atributo.

El método establecer para el atributo ventasBrutas (setVentasBrutas) debe


garantizar que el valor debe ser positivo, en caso de ser negativo se
asignará un cero.

El método establecer para tarifaComisión (setTarifaComision) garantiza que


la tarifa es un número real entre el valor 0,0 y 1,0 (no inclusive), en caso de
no ser así asigna el valor 0,0.

* Un método obtener (get) por cada atributo.

* Un método ingresos() que calcula los ingresos de un EmpleadoPorComision,


multiplicando la tarifaComision por las ventasBrutas y devuelve el resultado.

22-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

// calcula el salario del empleado por comisión


public double ingresos() {
return tarifaComision * ventasBrutas;
}

* Un método toString() que nos presenta un objeto de la clase


EmpleadoPorComision con el siguiente formato:

Empleado por comisión: Pepe Jones


número de seguro social: 28/6516895
ventas brutas: 500.00 €
tarifa de comisión: 0.10

El método toString de la clase EmpleadoPorComision sobrescribe (redefine) al


método toString de la clase Object.

La clase PruebaEmpleadoPorComision crea una instancia de un objeto


EmpleadoPorComision e invoca a su constructor pasando los valores.

Utiliza los métodos get de EmpleadoPorComision para obtener los valores de las variables de
instancia del objeto que se acaba de crear e imprimirlas en pantalla con el siguiente formato:

Información del empleado

Primer nombre es Pepe


Apellido paterno es Jones
Número de la seguridad social es 28/651458
Las ventas brutas son 1000,00
La tarifa de comisión es 0,10

Actualiza los valores de ventas brutas y tarifa de comisión, pasando directamente los valores
utilizando sus métodos establecer. Y después utiliza el método toString para imprimir el
Empleado por comisión actualizado:

Información actualizada del empleado, obtenida mediante toString:

Empleado por comisión: Pepe Jones


número de seguridad social: 28/651458
ventas brutas: 500,00
tarifa de comisión: 0,09

23-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Consideraciones ejemplo1

Los constructores no se heredan, por lo que la clase EmpleadoPorComision no


hereda el constructor de la clase Object.

El constructor de la clase EmpleadoPorComision llama al constructor de la clase Object


de manera implícita.

// constructor con cinco argumentos


public EmpleadoPorComision( String nombre, String apellido, String nss,
double ventas, double tarifa ) {
// la llamada implícita al constructor del objeto ocurre aquí
primerNombre = nombre;
apellidoPaterno = apellido;
numeroSeguroSocial = nss;
setVentasBrutas( ventas ); // valida y almacena las ventas brutas
setTarifaComision( tarifa ); // valida y almacena la tarifa de comisión
} // fin del constructor de EmpleadoPorComision con cinco argumentos

La primera tarea del constructor de cualquier subclase es llamar al


constructor de su superclase directa, ya sea en forma explícita o
implícita, para asegurar que las variables de instancia heredadas de la superclase se
inicialicen en forma apropiada.

Si el código no incluye una llamada explícita al constructor de la superclase, Java genera


una llamada implícita al constructor predeterminado o sin argumentos de la superclase
directa. El comentario en el siguiente código indica en dónde se hace la llamada implícita
al constructor predeterminado de la superclase Object

24-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

4.2 Ejemplo 2: creación de una clase EmpleadoBaseMasComision sin usar la herencia.

La clase EmpleadoBaseMasComision, contiene los siguientes atributos:

primerNombre
apellidoPaterno
numeroSeguridadSocial
ventasBrutas // ventas totales por semana
tarifa de comisión // porcentaje de comisión
salario base. // salario base por mes

Y los servicios public:

- Un constructor.

- Método ingresos, calcula los ingresos de un empleado por comisión con salario base:
salarioBase + ( tarifaComision * ventasBrutas )

- Método toString que devuelve un objeto String que representa la información del
EmpleadoPorComision con el siguiente formato:

Empleado por comision: Pepe Jones


número de seguro social: 28/6516895
ventas brutas: 500.00 €
tarifa de comisión: 0.10
salario base: 1000.00 €

- Métodos establecer y obtener public para las variables de instancia private primerNombre,
apellidoPaterno, numeroSeguridadSocial, ventasBrutas, tarifaComision y salarioBase.

El método establecer para el atributo ventasBrutas debe garantizar que el valor


debe ser positivo, en caso de ser negativo se asignará un cero.

El método establecer para tarifaComisión garantiza que la tarifa es un número real


entre el valor 0,0 y 1,0 (no inclusive), en caso de no ser así asigna el valor 0,0.

El método establecer para SalarioBase asegura que no se le asigne a la variable


salarioBase un valor negativo, ya que el salario base de un empleado no puede ser
negativo.

Estas variables y métodos encapsulan todas las características necesarias de un


empleado por comisión con sueldo base.

Observa la similitud entre esta clase y la clase EmpleadoPorComision ; en


este ejemplo, no explotamos todavía esa similitud mediante el uso de la herencia.

25-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

En la declaración de la clase EmpleadoBaseMasComision no especifiques “extends Object”,


la clase hereda de Object en forma implícita.

La clase PruebaEmpleadoBasePorComision:

- crea una instancia de un objeto EmpleadoBaseMasComision e invoca a su constructor


pasando los valores (primer nombre, apellido paterno, número de seguridad social, ventas
brutas, tarifa de comisión y salario base).

- Se utilizan los métodos obtener de EmpleadoBaseMasComision para


obtener los valores de las variables de instancia del objeto e imprimirlos en pantalla. Antes
escribimos la cabecera “Información del empleado:”

Actualiza el valor de salarioBase utilizando su método establecer. Y después, escribimos la


cabecera “Información actualiza del empleado, obtenida por toString:” y utiliza el método
toString para imprimir sus datos actualizados.

Información del empleado obtenida por métodos set:

El primer nombre es Bob


El apellido es Lewis
El numero de seguro social es 333-33-3333
Las ventas brutas son 5000,00
La tarifa de comision es 0,04
El salario base es 300,00

Información actualizada del empleado, obtenida por toString:

empleado por comisión con sueldo base: Bob Lewis


número de seguro social: 333-33-3333
ventas brutas: 5000,00
tarifa de comisión: 0,04
salario base: 1000,00

26-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Consideraciones ejemplo2.

La mayor parte del código para la clase EmpleadoBaseMasComision es idéntico al código


para la clase EmpleadoPorComision.

Lo que habitualmente se hace es copiar el código de la clase


EmpleadoPorComision

y lo pegamos en la clase
EmpleadoBaseMasComision,

después modificamos esta clase para incluir un salario base y los métodos que manipulan
ese salario base.

A menudo, este método de “copiar y pegar” provoca errores y además, se pueden esparcir
los errores por distintas copias físicas del mismo código a lo largo de un sistema, con lo que
el mantenimiento del código se convierte en una pesadilla.

¿Existe alguna manera de “absorber” las variables de instancia y los métodos de una clase, de
manera que formen parte de otras clases sin tener que copiar el código?

En los siguientes ejemplos responderemos a esta pregunta, utilizando la herencia.

Observación de ingeniería de software:

Copiar y pegar código de una clase a otra puede esparcir los errores a través de
varios archivos de código fuente. Para evitar la duplicación de código (y
posiblemente los errores) usa la herencia o, en algunos casos, la composición, en
vez del método de “copiar y pegar” cuando se desea que una clase “absorba” las
variables de instancia y los métodos de otra clase.

Con la herencia, las variables de instancia y los métodos comunes


de todas las clases en la jerarquía se declaran en una superclase.
Cuando se requieren modificaciones para estas características
comunes, los programadores sólo necesitan realizar las
modificaciones en la superclase; así las clases derivadas heredan
los cambios. Sin la herencia, habría que modificar todos los
archivos de código fuente que contengan una copia del código en
cuestión.

27-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

4.3 Ejemplo 3: creación de una jerarquía de herencia EmpleadoPorComision –


EmpleadoBaseMasComision.

Ahora declararemos la clase EmpleadoBaseMasComision2, que extiende (hereda de) a la


clase EmpleadoPorComision.

EmpleadoPorComision

EmpleadoBasePorComision2

public class EmpleadoBaseMasComision2 extends EmpleadoPorComision

La clase EmpleadoBasePorComision2 es una copia da la clase EmpleadoBasePorComision


quitando los atributos que hereda de la clase EmpleadoPorComision.

Importante:

- Un objeto EmpleadoBaseMasComision2 es un EmpleadoPorComision, al revés no es cierto.

- La subclase, EmpleadoBaseMasComision2 hereda los atributos y los métodos de la clase


EmpleadoPorComision.

- El constructor de la clase EmpleadoPorComision no se hereda.

- El constructor de cada subclase debe llamar en forma implícita o explícita al constructor de


su superclase, para asegurar que las variables de instancia heredadas de la superclase se
inicialicen en forma apropiada.

- El constructor de EmpleadoBaseMasComision2 con seis argumentos llama en forma


explícita al constructor de la clase EmpleadoPorComision con cinco argumentos:

super( nombre, apellido, nss, ventas, tarifa )

- Si el constructor de EmpleadoBaseMasComision2 no invocara al constructor de


EmpleadoPorComision de manera explícita, Java trataría de invocar al constructor
predeterminado o sin argumentos de la clase EmpleadoPorComision; pero como la clase no
tiene un constructor así, el compilador generaría un error.

28-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

- Los métodos ingresos y tostring de la clase EmpleadoBaseMasComision2 acceden


directamente a los atributos de EmpleadoPorComision(primerNombre, apellidoPaterno,
numeroSeguroSocial, ventasBrutas y tarifaComision) por herencia.

Prueba el funcionamiento de la clase EmpleadoBaseMasComision2.

29-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Consideraciones ejemplo3.

La llamada explícita al constructor de la superclase debe ser la primera instrucción en el


cuerpo del constructor de la subclase. Además, cuando una superclase contiene un
constructor sin argumentos, puede usar “super()” para llamar a ese constructor en forma
explícita, pero esto se hace raras veces.

Error común de programación:


Si el constructor de una subclase llama a uno de los constructores de su
superclase con argumentos que no concuerdan exactamente con el número y el
tipo de los parámetros especificados en una de las declaraciones del constructor de
la super-clase, se produce un error de compilación.

El método ingresos y toString genera errores debido a que las variables de instancia de la
superclase EmpleadoPorComision son private; no se permite a los métodos de la subclase
EmpleadoBaseMasComision2 acceder a las variables de instancia private de la superclase
EmpleadoPorComision.

public double ingresos() {


// no está permitido: tarifaComision y ventasBrutas son private en la superclase
return salarioBase + ( tarifaComision * ventasBrutas );
}

// devuelve representación String de EmpleadoBaseMasComision2


public String toString() {
// no está permitido: miembros private de la superclase
return String.format(
"%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f\n%s: %.2f",
"empleado por comision con sueldo base", primerNombre, apellidoPaterno,
"numero de seguro social", numeroSeguroSocial,
"ventas brutas", ventasBrutas, "tarifa de comision", tarifaComision,
"salario base", salarioBase );
}

Se hubieran podido prevenir los errores en EmpleadoBaseMasComision2 al utilizar los


métodos get (obtener) heredados de la clase EmpleadoPorComision.

En el ejemplo4 vamos a declarar las variables de instancia de la superclase


( EmpleadoPorComision) con el modificador de acceso protected.

30-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

4.4 Ejemplo 4: la jerarquía de herencia EmpleadoPorComision - EmpleadoBaseMasComision


mediante el uso de variables de instancia protected.

Para permitir que la clase EmpleadoBaseMasComision acceda directamente a las variables


de instancia primerNombre, apellidoPaterno, numeroSegurIdadSocial, ventasBrutas y
tarifaComision de la superclase, podemos declarar esos miembros como protected en la
superclase (EmpleadoPorComision2 ).

Los miembros protected de una superclase se heredan por todas las subclases de esa
superclase.

Aparte del cambio en el nombre de la clase EmpleadoPorComision2 (y por ende el cambio en


el nombre del constructor) el resto de la declaración de la clase es idéntico a
EmpleadoPorComision.

EmpleadoPorComision2

EmpleadoBasePorComision3

Podríamos haber declarado las variables de instancia primerNombre, apellidoPaterno,


numeroSeguridadSocial, ventasBrutas y tarifaComision de la superclase
EmpleadoPorComision2 como public, para permitir que la subclase
EmpleadoBaseMasComision2 pueda acceder a las variables de instancia de la superclase.
No obstante, declarar variables de instancia public es una opción inadecuada, ya que permite
el acceso sin restricciones a las variables de instancia, lo cual incrementa considerablemente
la probabilidad de errores.

Con las variables de instancia protected, la subclase obtiene acceso a las variables de
instancia, pero las clases que no son subclases y las clases que no están en el mismo
paquete no pueden acceder a estas variables en forma directa; recuerda que los miembros
de clase protected son también visibles para las otras clases en el mismo paquete.

Observa que los resultados utilizando el objeto EmpleadoBaseMasComision3 es el mismo


que la aplicación que utilizo la clase EmpleadoBaseMasComision.

31-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Información del empleado obtenida por métodos establecer:

El primer nombre es Pepe


El apellido es Lewis
El numero de seguro social es 28/6194561
Las ventas brutas son 5000,00
La tarifa de comisión es 0,04
El salario base es 300,00

Información actualizada del empleado, obtenida por toString:

empleado por comisión con sueldo base: Pepe Lewis


número de seguro social: 28/6194561
ventas brutas: 5000,00
tarifa de comisión: 0,04
salario base: 1500,00

Consideraciones ejemplo4.

En este ejemplo declaramos las variables de instancia de la superclase como protected, para
que las subclases pudieran heredarlas. El uso de variables de instancia protected
crea varios problemas potenciales:

En primer lugar, el objeto de la subclase puede establecer el valor de una variable heredada
directamente, sin utilizar un método establecer(set). Por lo tanto, un objeto de la
subclase puede asignar un valor inválido a la variable, con lo cual el objeto
queda en un estado inconsistente.

El segundo problema con el uso de variables de instancia protected es que hay más
probabilidad de que los métodos de la subclase se escriban de manera que dependan de la
implementación de datos de la superclase. Si hay variables de instancia protected en la
superclase, tal vez necesitemos modificar todas las subclases de esa superclase si cambia la
implementación de ésta. Por ejemplo, si por alguna razón tuviéramos que cambiar los
nombres de las variables de instancia primerNombre y apellidoPaterno por nombre y apellido,
entonces tendríamos que hacerlo para todas las ocurrencias en las que una subclase haga
referencia directa a las variables de instancia primerNombre y apellidoPaterno de la
superclase. En tal caso, se dice que el software es frágil o quebradizo, ya que un pequeño
cambio en la superclase puede “quebrar” la implementación de la subclase. Es
conveniente que el programador pueda modificar la implementación de la
superclase sin dejar de proporcionar los mismos servicios a las subclases.

32-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Un tercer problema es que los miembros protected de una clase son visibles para todas las
clases que se encuentren en el mismo paquete que la clase que contiene los miembros
protected; esto no siempre es conveniente.

Observación de ingeniería de software:

- Usa el modificador de acceso protected cuando una superclase deba proporcionar


un método sólo a sus subclases y a otras clases en el mismo paquete, pero no a
otros clientes.

- Al declarar variables de instancia private (a diferencia de protected) en la


superclase, se permite que la implementación de la superclase para estas variables
de instancia cambie sin afectar las implementaciones de las subclases.

- Siempre que sea posible, no incluyas variables de instancia protected en una


superclase. En vez de ello, incluye métodos no private que accedan a las variables
de instancia private. Esto asegurará que los objetos de la clase mantengan estados
consistentes.

33-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

4.5 Ejemplo 5: la jerarquía de herencia EmpleadoPorComision - EmpleadoBaseMasComision


mediante el uso de variables de instancia private.

En este ejemplo utilizamos las mejores prácticas de ingeniería


de software de la POO, la herencia (reutilizar código) y ocultamiento (atributos private).

EmpleadoPorComision3

EmpleadoBaseMasComision4

La clase EmpleadoPorComision3 declara las variables de instancia primerNombre,


apellidoPaterno, numeroSeguridadSocial, ventasBrutas y tarifaComision como private y
proporciona los métodos public establecer y obtener, ingresos y toString para manipular estos
valores.

private String primerNombre;


private String apellidoPaterno;
private String numeroSeguroSocial;
private double ventasBrutas; // monto de ventas (es decir, total)
private double tarifaComision; // porcentaje de comisión

Los métodos ingresos y toString deben utilizar los métodos obtener (get) de la clase. Si
decidimos modificar los nombres de las variables de instancia, no habrá que modificar las
declaraciones de ingresos y de toString; sólo habrá que modificar los cuerpos de los métodos
obtener y establecer que manipulan directamente estas variables de instancia.

// calcula el salario del empleado por comisión


public double ingresos() {
return getTarifaComision() * getVentasBrutas();
}

// devuelve representación String del objeto EmpleadoPorComision


public String toString() {
return String.format( "%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f",
"empleado por comision", getPrimerNombre(), getApellidoPaterno(),
"numero de seguridad social", getNumeroSeguroSocial(),
"ventas brutas", getVentasBrutas(),
"tarifa de comision", getTarifaComision() );
}

34-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

La nueva versión obtiene la porción de los ingresos del empleado, con base en la comisión
solamente, mediante una llamada al método ingresos de EmpleadoPorComision3 con la
expresión super.ingresos(). El método ingresos de EmpleadoBasePorComision4 suma
después el salario base a este valor, para calcular los ingresos totales del empleado.

// calcula los ingresos


public double ingresos() {
return getSalarioBase() + super.ingresos();
}

Al hacer que el método ingresos de EmpleadoBaseMasComision4 invoque al método


ingresos de EmpleadoPorComision3 para calcular parte de los ingresos del objeto, evitamos
duplicar el código y se reducen los problemas de mantenimiento del mismo.

Observa la sintaxis utilizada para invocar un método sobrescrito de la superclase desde una
subclase: super y un punto (.) antes del nombre del método de la superclase.

Si un método realiza todas o algunas de las acciones que necesita otro método, se hace una
llamada a ese método en vez de duplicar su código. Esta forma de invocar métodos es una
buena práctica de ingeniería de software

Error común de programación:


Si no se antepone al nombre del método de la superclase la palabra clave super y
el separador punto (.) cuando se hace referencia al método de la superclase, el
método de la subclase se llama a sí mismo, creando potencialmente un error
conocido como recursividad infinita.

De manera similar, el método toString de EmpleadoBaseMasComision4 sobrescribe el


método toString de la clase EmpleadoPorComision3 :

// devuelve representación String de EmpleadoBaseMasComision4


public String toString() {
return String.format( "%s %s\n%s: %.2f", "con sueldo base",
super.toString(), "sueldo base", getSalarioBase() );
}

En esta sección hemos estudiado la evolución de un conjunto de ejemplos diseñados para


enseñar las capacidades de la herencia en Java, utilizando buenas prácticas de ingeniería
de software, para crear clases que sean fáciles de mantener, modificar y depurar.

35-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

5. Ingeniería de software mediante la herencia

Java sólo requiere el acceso al archivo .class de la superclase, para poder compilar y
ejecutar cualquier programa que utilice o extienda la superclase.

Esta poderosa capacidad hace que Java sea muy atractivo para los programadores
independientes, quienes pueden desarrollar clases propietarias y ponerlas a disposición de
los usuarios en formato de bytecode. Después, los usuarios pueden hacer nuevas clases a
partir de estas clases de biblioteca, sin necesidad de acceder al código fuente propietario.

A pesar del hecho de que al heredar de una clase no se requiere acceso al código fuente de
esa clase, en muchas ocasiones, los programadores insisten en ver el código fuente para
comprender cómo está implementada dicha clase.

Observaciones:

• Declarar una subclase no afecta el código fuente de la superclase. La


herencia preserva la integridad de la superclase.

• La programación orientada a objetos facilita la reutilización de software, con


lo que se obtiene una potencial reducción en el tiempo de desarrollo.

• Es conveniente que el diseñador coloque en una superclase las variables de


instancia y los métodos comunes. Después debe usar la herencia para
desarrollar subclases, especializándolas.

36-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

6. La clase object

Todas las clases en Java heredan, ya sea en forma directa o indirecta de la clase Object
(paquete java.lang), por lo que todas las demás clases heredan sus 11 métodos.

Algunos métodos de la clase Object:

clone
Este método protected, que no recibe argumentos y devuelve una referencia Object, realiza
una copia del objeto en el que se llama. Cuando se requiere la clonación para los objetos de
una clase, ésta debe sobrescribir el método clone como un método public, y debe
implementar la interfaz Cloneable (paquete java.lang). La implementación predeterminada de
este método realiza algo que se conoce como copia superficial: los valores de las variables
de instancia en un objeto se copian a otro objeto del mismo tipo. Para los tipos por referencia,
sólo se copian las referencias.

equals
Este método compara la igualdad entre dos objetos; devuelve true si son iguales y false en
caso contrario. El método recibe cualquier objeto como argumento. Cuando debe compararse
la igualdad entre objetos de una clase en particular, la clase debe sobrescribir el método
equals para comparar el contenido de los dos objetos.

finalize
El recolector de basura llama a este método protected para realizar tareas previas sobre
ojetos no referenciados.

getClass
Todo objeto en Java conoce su tipo en tiempo de ejecución. El método getClass devuelve un
objeto de la clase Class (paquete java.lang), el cual contiene información acerca del tipo del
objeto, como el nombre de su clase.

hashCode
Devuelve un identificador unívoco después de aplicarle un algoritmo hash.

toString
Este método devuelve una representación String de un objeto. La implementación
predeterminada de este método devuelve el nombre del paquete y el nombre de la clase del
objeto, seguidos por una representación hexadecimal del valor devuelto por el método
hashCode del objeto.

37-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Ejemplo 6 Prueba de métodos heredados de Object.

public class Alumno {

String nombre;
String instituto;
int edad;
public Alumno(String nombre, String instituto, int edad) {
this.nombre = nombre;
this.instituto = instituto;
this.edad = edad;
}
}

public class TestAlumno {

public static void main(String[] args) {


Alumno alum=new Alumno("Pepe", "Donoso",19) ;
System.out.println("Alumno "+alum);
System.out.println("\ntoString():"+alum.toString());
System.out.println("\nhashCode(): "+alum.hashCode());
System.out.println("\ngetClass(): "+alum.getClass());
System.out.println("\nalum==alum: "+alum.equals(alum));
}
}

38-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

7 Los constructores en las subclases

Al crear una instancia de un objeto de una subclase se empieza una cadena de llamadas a
los constructores: el constructor de la subclase invoca al constructor de su superclase, ya
sea en forma explícita (por medio de la referencia super) o implícita (llamando al constructor
predeterminado o sin argumentos de la superclase). Si la superclase se deriva de otra clase
(como sucede con cualquier clase, excepto Object), el constructor de la superclase invoca al
constructor de la siguiente clase que se encuentre a un nivel más arriba en la jerarquía, y así
sucesivamente.

El último constructor que se llama en la cadena es siempre el de la clase Object.

El constructor de la clase Object tiene un cuerpo vacío.

A tener en cuenta:
Java asegura que, aún si un constructor no asigna un valor a una variable de
instancia, la variable de todas formas se inicializa con su valor predeterminado (es
decir, 0 para los tipos numéricos primitivos, false para los tipos boolean y null para
las referencias).

39-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Ejemplo 7. Utilizando las clases del ejemplo 5 (EmpleadoBaseMasComision4 que hereda de


EmpleadoPorComision3) , modificar sus constructores para que impriman un mensaje
cuando se le invoca, lo cual nos permitirá observar el orden en el que se ejecutan los
constructores en la jerarquía.

Constructores:

Superclase:

public EmpleadoPorComision3( String nombre, String apellido, String nss, double ventas,
double tarifa ) {

// la llamada implícita al constructor de Object ocurre aquí


primerNombre = nombre;
apellidoPaterno = apellido;
numeroSeguroSocial = nss;
setVentasBrutas( ventas ); // valida y almacena las ventas brutas
setTarifaComision( tarifa ); // valida y almacena la tarifa de comisión
System.out.printf( "\nConstructor de EmpleadoPorComision3:\n%s\n", this );

Subclase:

public EmpleadoBaseMasComision4( String nombre, String apellido, String nss, double


ventas, double tarifa, double salario ) {

super( nombre, apellido, nss, ventas, tarifa );


setSalarioBase( salario ); // valida y almacena el salario base
System.out.printf( "\nConstructor de EmpleadoBaseMasComision4:\n%s\n",
this );

40-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

La siguiente clase (PruebaConstructores) muestra el orden en el que se llaman los


constructores de la superclase y la subclase.

public class PruebaConstructores {

public static void main( String args[] ) {

EmpleadoBaseMasComision4 empleado1 =
new EmpleadoBaseMasComision4(
"Lisa", "Simpson", "10/123456", 2000, .06, 800 );
System.out.println();
EmpleadoBaseMasComision4 empleado2 =
new EmpleadoBaseMasComision4(
"Mark", "Pasado del Río", "88/888-8888", 8000, .15, 2000 );

}
}

Ejecución:

Constructor de EmpleadoPorComision3:
con sueldo base empleado por comision: Lisa Simpson
numero de seguridad social: 10/123456
ventas brutas: 2000,00
tarifa de comision: 0,06
sueldo base: 0,00

Constructor de EmpleadoBaseMasComision4:
con sueldo base empleado por comision: Lisa Simpson
numero de seguridad social: 10/123456
ventas brutas: 2000,00
tarifa de comision: 0,06
sueldo base: 800,00

Constructor de EmpleadoPorComision3:
con sueldo base empleado por comision: Mark Pasado del Río
numero de seguridad social: 88/888-8888
ventas brutas: 8000,00
tarifa de comision: 0,15
sueldo base: 0,00

Constructor de EmpleadoBaseMasComision4:
con sueldo base empleado por comision: Mark Pasado del Río
numero de seguridad social: 88/888-8888
ventas brutas: 8000,00
tarifa de comision: 0,15
sueldo base: 2000,00

41-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Ejemplo 8. De Herencia y Composición

En una empresa X existen tres tipos de empleados: administrativos, directivos y comerciales; sus
caracteríticas comunes se recogen en la clase Empleado.

Crear una clase llamada Empleado de la que van a heredar las clases Administrativo, Directivo y
Comercial.

Atributos de la clase Empleado:


- nombreEmpleado
- extensionTelefonica (cadena de tres dígitos numéricos que debe empezar por cero, por
ejemplo “022”)
Para cualquier valor erroneo se asigna “000”
- salarioBruto (salario mínimo =735,90€)
Para cualquier valor inferior se asigna el salario mínimo
- impuestos (número entero entre 0 y 21, inclusives; expresa el porcentaje de impuestos).
Para cualquier valor inferior se asigna 0 y para cualquier valor superior se asigna 21.
- numeroHijos
- departamento, es una referencia a un objeto tipo Departamento.

Métodos de la clase Empleado:


Constructor sin parámetros y con parámetros para inicializar todos los atributos.
Métodos establecer y obtener para cada atributo
Método toString
Método ingresos, nos devuelve el salario del empleado descontado los impuestos.
salarioBruto – salarioBruto *(impuestos/100)

Los empleados están asignados a un departamento del que se desea guardar cierta información, así
que se ha de crear una clase Departamento con las siguientes variables miembro:
- nombreDepartamento
- nombreEmpleadoJefe
- presupuesto anual en €.

La clase Departamento tiene un constructor, un método toString, métodos establecer y obtener.

Las clases Directivo, Comercial y Administrativo modelan los empleados que tienen dicha
función, dichas clases heredan de la clase Empleado y presentan las siguientes particularidades:

• Los directivos cobran un plus de responsabilidad por su trabajo, su atributo


plusResponsabilidad recoge dicho importe neto. La clase Directivo tiene, además los
atributos de la clase Empleado.

• Los comerciales cobran una comisión y un kilometraje neto que se modelan en la clase
Comercial como dos atributos de tipo double. La clase Comercial tiene, además los atributos
de la clase Empleado.

• La clase Administrativo comparte los atributos de la clase Empleado.

42-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Las clases Directivo, Comercial y Administrativo:

- Sobre-escriben los métodos toString e ingresos. Los complementos salariales son netos (ya
tienen aplicado el descuento de los impuestos).

Ejemplo de ejecución del método toSting de un empleado de tipo Comercial:

Empleado Comercial
nombre: Lucas Ramírez
extensión telefónica: 023
salario bruto: 950.5
impuesto: 15%
hijos: 2
Departamento
nombre: informática
jefe: Nicolás Sánchez
presupuesto:9.500.000,0 €
Complementos salariales
comisión:1000.5
kilometraje:60.5

- Tienen dos constructores, uno para crear instancias con los valores por defecto para los
atributos y otro en el que se informa de todos los valores.

- Metodos establecer y obtener para sus atributos.

Crear una clase ControladorEmpleado1 que realice al menos las siguientes acciones:

• Crear un empleado de cada categoría (administrativo, directivo y comercial) para un mismo


departamento.
• Visualizar la información de cada empleado (toString) e imprime su salario neto (invocar su
método ingresos). Ejemplo de ejecución:

Empleado Comercial
nombre: Lucas Ramirez
extensión telefónica: 023
salario bruto: 950.5
impuesto: 15%
hijos: 2
Departamento
nombre: informática
jefe: null
presupuesto:9.500.000,0 €
Complementos salariales
comisión:1000.5
kilometraje:60.5

Salario neto .................1868.925

43-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Crear una clase ControladorEmpleado2 que realice al menos las siguientes acciones:

• Crear un empleado de cada categoría sin valores (administrativo, directivo y comercial)


para un mismo departamento.
• Visualizar la información de cada empleado (toString) e imprime su salario neto (invocar su
método ingresos).

Antes de empezar con la programación realiza el diagrama de clases en Lenguaje Unificado de


Modelado (UML).

EMPLEADO DEPARTAMENTO

ADMINITRATIVO DIRECTIVO COMERCIAL

Documenta tu programa con la herramienta javadoc.

https://web.dit.upm.es/~pepe/doc/fprg/javadoc.htm

http://hflorezf-es.blogspot.com.es/2012/09/java-doc.html

Se debe crear un proyecto con el primer apellido y el nombre del alumno:


apellido1_nombre_tema11_ejemplo8

Asegúrate que el nombre no contenga la letra ñ, tildes ni caracteres especiales extraños. Y un


paquete: ejemplo8.

La entrega es un único fichero comprimido que deberá contener:

- El modelo de datos: diagrama UML


- El proyecto.
- La API de la aplicación.

44-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Ejemplo 9. Array de elementos de la superclase.

Creamos un array de elementos de la superclase Empleado.

Utilizando la jerarquía de clases del ejemplo anterior realiza una aplicación (clase
RunApp, por ejemplo) que cree un array de 5 objetos de tipo Empleado.

Empleado arrayEmpleado [ ] = new Empleado(5);

Inserta en el array al menos tres empleados: un administrativo, un directivo y un


comercial.

Recorre el array y muestra su contenido, escribe el método toString de cada objeto de tipo
Empleado guardado en el array.

45-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Ejercicio 1 - Cuentas Bancarias

En un banco se manejan dos tipo de cuentas bancarias:

- Cuentas de Ahorro
- Cuentas Corrientes

Estos dos tipos de cuentas son idénticos excepto en las siguientes diferencias:

* Las cuentas de ahorro se numeran como 5XXXX y las cuentas corrientes se numeran
como 2XXXX. Cada vez que se crea una nueva cuenta, se debe generar su identificador:
– En las cuentas corrientes 20001, 20002, 20003 ….
– En las cuentas de ahorro 50001, 50002, 50003 …..
Siendo el primer dígito el identificador de cuenta corriente o cuenta de ahorro y el resto
(0001, 0002, 0003) el número de cuenta secuencial que se genera automáticamente cuando
se crea la cuenta.

* Cada cuenta tiene un contador propio que va indicar el número de cuenta (objeto) de cada
clase que se crea.

* Las cuentas corrientes tienen un cargo mensual de mantenimiento de 5 €/mes, con


independencia de su saldo. Las cuentas de ahorro no tienen cargo si el saldo supera los 200
euros, en caso contrario se cobran 5 € por mes, igual que cuenta corriente.

* Las cuentas corrientes no se les paga interés si el saldo no supera los 500 euros. Las
cuentas de ahorro siempre se les paga interés.

De la cuenta corriente y la cuenta de ahorro se guarda el identificador (id), el titular (nombre del
titular de la cuenta), el saldo y el interés anual (interesAnual, 8%).

Cuenta corriente y cuenta de ahorro tienen además, las siguientes funcionalidades:

– Generar Id.
– Ingresar dinero, se suma (ingresa) una cantidad dada al saldo.
– Sacar dinero, se resta (saca) una cantidad dada al saldo.
– Cargo mensual de mantenimiento de cuenta, se resta al saldo.
– Se cobran los intereses mensualmente (lo que corresponde a un mes del interés anual), se
suma a la cuenta.
– Método de representación de la cuenta bancaria, toString().

46-47
Tema 11. Programación orientada a objetos: Herencia. Curso 2018/2019

Siguiendo los principios de reutilización de código (se detectan clases con un comportamiento
común ) y especialización (se detecta que una clase es un caso especial de otra ), se puede modelar
el problema a través de una jerarquía de clases.

¿Puedes obtener una clase general con las características comunes de cuenta corriente y
cuenta de ahorros?

Superclase CuentaBancaria

Subclases CuentaCorriente CuentaAhorro

La clase CuentaBancaria es la que contiene las características comunes de la clase CuentaCorriente


y CuentaAhorro, no se va utilizar para crear objetos (los objetos que se van a utilizar son de la clase
CuentaCorriente y CuentaAhorro, pero no de la clase CuentaBancaria). Este tipo de clase se deben
declarar como abstracta (abstract).

public abstract class CuentaBancaria

Las clases abstractas solamente se pueden usar como clases base para otras clases. No se pueden
crear objetos pertenecientes a una clase abstracta.

Define la superclase CuentaBancaria y las subclases CuentaCorriente y CuentaAhorro, y además,


realiza una aplicación que cree dos cuentas (corriente y de ahorro) con un saldo inicial de 1000 €.
Muestra su funcionamiento (a modo de ejemplo) durante 10 meses, para cada mes se deben realizar
las siguientes operaciones:

Ingresar cada mes 100 euros.


Calcular y mostrar para cada mes el cargo mensual.
Calcular y mostrar para cada mes el interés mensual.
Mostrar la información de cada cuenta (método toString) después de realizar las operaciones
indicadas.

47-47

También podría gustarte