Está en la página 1de 66

22/04/2019

MÓDULO PROFESIONAL UD 6 – Manejo avanzado de

PROGRAMACIÓN clases

CONTENIDO
 Composición
 Herencia
 Concepto
 Herencia en Java
 Superclases y subclases

 Polimorfismo
 Concepto
 Upcasting y downcasting
 El operador de casting
 El operador instanceOf

 Clases y métodos abstractos


 Interfaces
 La interfaz Comparable

 Diseño orientado a objetos


 Encapsulamiento
 Cohesión
 Acoplamiento

1
22/04/2019

COMPOSICIÓN
Vamos a ver el concepto de herencia que es imprescindible para
la reutilización de código y la descomposición de problemas en
subproblemas para su resolución.
Pero antes hagamos un repaso al concepto de composición visto
con anterioridad y que nos ha servido para reutilizar código

COMPOSICIÓN
Revisaremos con la reutilización de las clases a través de la composición, a través de
ejemplos. Comenzaremos con la clase Autor (Author)

2
22/04/2019

COMPOSICIÓN
Un libro (Book) es escrito por un autor (Author): usando un variable miembro "Objeto"

3
22/04/2019

COMPOSICIÓN
Veamos otro ejemplo de reutilización de una clase a través de la composición,
supongamos que tenemos una clase llamada Punto (Point), definida como se muestra
en el diagrama de clase anterior.

COMPOSICIÓN
Supongamos que necesitamos una nueva clase llamada Línea (Line), podemos diseñar
la clase Línea reutilizando la clase Punto a través de la composición. Decimos que
"Una línea se compone de dos puntos" o "Una línea tiene dos puntos". La composición
exhibe una relación “tiene-un".

4
22/04/2019

ACTIVIDAD 1

COMPOSICIÓN
Supongamos que tenemos una clase llamada Punto (Point), definida como se muestra
en el diagrama de clases. Una clase llamada Círculo (Circle) está diseñada como se
muestra en el diagrama de clase.

5
22/04/2019

HERENCIA
Al inicio hemos dicho que la herencia es imprescindible para la reutilización
de código y la descomposición de problemas en subproblemas para su
resolución.
En la POO la herencia consiste en la creación de clases a partir de otras ya
existentes. De este modo, la nueva clase o clase hija (subclase, clase
derivada o clase hija) “hereda” los atributos y métodos de la clase padre
(superclase, clase base o clase padre) además de y crear nuevos atributos y
métodos e incluso modificar los heredados.

6
22/04/2019

HERENCIA
Es la base de la reutilización de código ya que cuando una clase hereda de
una clase padre obtiene los miembros y métodos de este sin tener que
duplicar el código.
En general todas las subclases no sólo adoptan las variables y
comportamientos de las superclases sino que los amplían y/o modifican

HERENCIA
La herencia genera una jerarquía de clases que se basa en la existencia de
relaciones de generalización y especialización entre clases.
En JAVA sólo está permitida la herencia simple, es decir, una clase puede tener muchas
subclases pero una clase sólo puede tener una superclase

Una subclase es un caso específico de una superclase

7
22/04/2019

HERENCIA
La herencia es transitiva, es decir si B hereda de A y C hereda de B, entonces
también C hereda de A.
C->B->A
C no sólo hereda de B sino que también hereda de A.
Los métodos y atributos siempre se pueden heredar exactamente igual que en los
ancestros o modificarlos (generalmente modificando su comportamiento pero
manteniendo su esencia).
En algunas ocasiones una subclase puede seguir utilizando ambos
comportamientos, el heredado y el redefinido.

HERENCIA
Cuando una clase hereda de otra, la clase hija tiene acceso a todos (o casi todos) los
elementos de la clase padre, pero la clase padre no puede acceder a los elementos
de la clase hija. Ejemplo:

8
22/04/2019

HERENCIA

HERENCIA EN JAVA
Por defecto en JAVA todas las clases heredan de la clase java.lang.Object.
Si al definir nuestra clase no indicamos nada, esta por defecto será una clase
de la clase object.

La clase Object define e implementa los comportamientos comunes que se


requieren de todos los objetos Java que se ejecutan bajo el JRE.

9
22/04/2019

HERENCIA EN JAVA
Para indicar que una clase hereda de otra se utiliza la palabra reservada extends
mod_acceso Clase_hija extends Clase_padre {
//código de la clase
}
Public class Cuadrado extends Poligono {
//código de la clase
}

HERENCIA
class Goalkeeper extends SoccerPlayer {......}

10
22/04/2019

HERENCIA
Notación UML

Notación UML: La notación UML para herencia es una línea sólida con una punta de flecha
hueca que va de la subclase a su superclase. Por convención, la superclase se dibuja sobre sus
subclases como se muestra.

HERENCIA EN JAVA
Hasta ahora trabajamos principalmente con public y private. Con la herencia
utilizaremos frecuentemente un nuevo tipo: protected.
 public: Todos pueden acceder a el.
 private: Sólo es accesible desde la propia clase.
 protected: : Accesible por las clases del mismo paquete y subclases.

11
22/04/2019

HERENCIA EN JAVA
Por tanto al heredar de una clase, heredamos todos los métodos y atributos
públicos y protected de la clase padre.
 Los constructores nunca se heredan, aunque se pueden invocar desde los
constructores de la clase hija para reutilizarlos (lo veremos más adelante).
 Al heredar de una clase, podemos acceder y utilizar los atributos y métodos
de esta clase como si fueran propios , simplemente por haber hecho
referencia a la clase padre con la palabra reservada extends

HERENCIA EN JAVA
Cuando heredamos un método de una clase, podemos utilizarlo de forma
idéntica al padre o adaptarlo para que encaje mejor en la nueva clase.
 En definitiva redefinir un método consiste en reimplementar lo en la clase
hija
 Para redefinir un método en una subclase basta con declararlo con el
mismo nombre, los mismos atributos y el mismo tipo de dato devuelto.

12
22/04/2019

HERENCIA EN JAVA
No confundir redefinir un método con sobrecargar un método
 Sobrecargar un método consiste en definir 2 o más métodos con el mismo nombre y
tipo de dato devuelto pero que difieren en el número y/o tipo de argumentos que
reciben

HERENCIA EN JAVA

13
22/04/2019

SUPERCLASES Y SUBCLASES
A pesar de redefinir un método, desde una clase hija se puede seguir
utilizando el método original de la clase padre.
Esto es especialmente útil cuando el nuevo método realiza las mismas
acciones que el método padre más otras nuevas.
Para ello se utilizan los modificadores this y super.

SUPERCLASES Y SUBCLASES
this hace referencia al objeto de la clase actual (hijo):
this.atributo; this.método();

super hace referencia a los métodos o atributos de la clase padre:


super.atributo; super.método();

14
22/04/2019

SUPERCLASES Y SUBCLASES
Ejemplo

SUPERCLASES Y SUBCLASES
Ejemplo

15
22/04/2019

SUPERCLASES Y SUBCLASES
Recuerda que la subclase hereda todas las variables y métodos de sus superclases.
No obstante, una subclase no hereda a los constructores de sus superclases. Cada
clase en Java define sus propios constructores.
En el cuerpo de un constructor, puede usar super(args) para invocar a un constructor
de su superclase inmediata. Ten en cuenta que super(args), si se usa, debe ser la
primera declaración en el constructor de la subclase.
Esto sigue al hecho de que el padre debe nacer antes de que el niño pueda nacer.
Se debe construir correctamente las superclases antes de poder construir la subclase.

SUPERCLASES Y SUBCLASES. CONSTRUCTOR POR


DEFECTO
Si no se define ningún constructor en una clase, el compilador de Java crea automáticamente un
constructor sin argumentos (no-arg), que simplemente emite una llamada super(), de la siguiente
manera:

Toma nota de que:


El constructor por defecto no se generará automáticamente, si se definió uno (o más) constructores.
En otras palabras, debe definir el constructor sin argumentos explícitamente si se definieron otros
constructores.
Si la superclase inmediata no tiene el constructor por defecto (define algunos constructores pero no
define un constructor sin argumentos), obtendrá un error de compilación al hacer una llamada
super(). Tenga en cuenta que el compilador Java inserta un super() como la primera declaración en
un constructor si no hay un super(args).

16
22/04/2019

SUPERCLASES Y SUBCLASES
Una subclase hereda todas las variables y métodos miembros de sus superclases
(el padre inmediato y todos sus ancestros). Puede utilizar los métodos y variables
heredados como son. También puede redefinir un método heredado al proporcionar
su propia versión u ocultar una variable heredada al definir una variable del mismo
nombre.
Por ejemplo, el método heredado getArea() en un objeto Cilindro calcula el área
base del cilindro. Supongamos que decidimos redefinir getArea() para calcular el
área de superficie del cilindro en la subclase Cilindro. A continuación se presentan los
cambios:

ACTIVIDAD 2
Crea las clases Circulo, Cilindro y PruebaCilindro
En este ejemplo, derivamos una subclase llamada
Cilindro de la superclase Círculo, que hemos creado
revisando el concepto de composición.
Es importante tener en cuenta que reutilizamos la clase
Círculo. La reutilización es una de las propiedades más
importantes de la POO.
(¿Por qué reinventar las ruedas?) La clase Cylinder
hereda todas las variables miembro (radio y color) y
métodos (getRadius (), getArea (), entre otros) de su
superclase Circle. Además, define una variable llamada
altura, dos métodos públicos: getHeight () y getVolume()
y sus propios constructores, como se muestra:

17
22/04/2019

18
22/04/2019

ANOTACIÓN OVERRIDE
El "@override" se conoce como anotación (introducida en JDK 1.5), que le pide al
compilador que verifique si existe un método de este tipo en la superclase a ser
redefinido.
Esto ayuda enormemente si escribe incorrectamente el nombre del método que se va
a redefinir. Por ejemplo, suponga que desea redefinir el método toString () en una
subclase. Si no se usa @override y toString () se escribe mal como TOString (), se
tratará como un nuevo método en la subclase, en lugar de reemplazar la superclase.
Si se usa @override, el compilador señalará un error.
La anotación de @override es opcional, pero ciertamente agradable de tener.
Las anotaciones no son construcciones de programación. No tienen efecto en la salida
del programa. Solo lo usa el compilador, se desecha después de la compilación y no
lo usa el tiempo de ejecución.

ACTIVIDAD 3
Crea las clases Punto2D, Punto3D y
una clase PruebaPuntos

19
22/04/2019

20
22/04/2019

ACTIVIDAD 4
Crea las clases Persona,
Alumno, Profesor y
PruebaPersona

21
22/04/2019

COMPOSICIÓN VS HERENCIA
"Una línea se compone de 2 puntos" vs. "Una línea es un punto
extendido por otro punto“
Recuerda que hay dos formas de reutilizar las clases existentes: la
composición y la herencia.

22
22/04/2019

COMPOSICIÓN VS HERENCIA
Hemos visto que una clase de
línea se puede implementar
utilizando la composición de la
clase de puntos: "Una línea se
compone de dos puntos", en la
sección anterior
También se puede implementar
una línea, utilizando la herencia
de la clase Punto: "Una línea es
un punto extendido por otro
punto". Llamemos a esta
subclase LineSub (para
diferenciarnos de la clase Line
usando composición).

ACTIVIDAD 5
Crea las clases
LineSub
Y TestLineSub

23
22/04/2019

ACTIVIDAD 5
Estudia ambas versiones de la clase Linea (Line y
LineSub). Supongo que es más fácil decir que
"Una línea se compone de dos puntos" que
"Una línea es un punto extendido por otro
punto".

COMPOSICIÓN VS HERENCIA

Regla de oro: usa la composición si es posible, antes de considerar la herencia. Utilice


la herencia solo si existe una clara relación jerárquica entre las clases.

24
22/04/2019

ACTIVIDAD 6
Las clases de Circle y Cylinder usando composición
Intenta volver a escribir el Círculo-Cilindro del ejercicio anterior
usando la composición (como se muestra en el diagrama de
clase) en lugar de la herencia. Es decir, "un cilindro está
compuesto por un círculo base y una altura".

¿Qué diseño (herencia o composición) es mejor?

HERENCIA VS COMPOSICIÓN

25
22/04/2019

ACTIVIDAD 7

ACTIVIDAD 8

26
22/04/2019

ACTIVIDAD 9
Enunciado en el aula virtual

POLIMORFISMO
La palabra "polimorfismo" significa "muchas formas". Viene de la palabra griega
"poli" (significa muchos) y "morfos" (significa forma).
Por ejemplo, en química, el carbono exhibe polimorfismo porque se puede encontrar
en más de una forma: grafito y diamante. Pero, cada una de las formas tiene
propiedades distintas (y precio).

27
22/04/2019

POLIMORFISMO
Sustituibilidad
Una subclase posee todos los atributos y operaciones de su superclase (porque una
subclase hereda los atributos y operaciones de su superclase).
Esto significa que un objeto de subclase puede hacer lo que su superclase puede
hacer.
Como resultado, podemos sustituir una instancia de subclase cuando se espera
una instancia de superclase, y todo funcionará bien. Esto se llama sustituibilidad.

POLIMORFISMO

En nuestro ejemplo anterior de


Círculo y Cilindro: Cilindro es una
subclase de Círculo.
Podemos decir que el Cilindro "es-
un" Círculo (en realidad, es "más
que un" Círculo). Las subclase-
superclase exhiben una relación
llamada “es-un” ("is-a“).

28
22/04/2019

POLIMORFISMO

POLIMORFISMO
Mediante la posibilidad de sustitución, podemos crear una instancia de Cilindro y
asignarla a una referencia de Círculo (su superclase), de la siguiente manera:

Puedes invocar todos los métodos definidos en la clase Circulo para la referencia c1,
(que en realidad contiene un objeto Cilindro), por ejemplo.

29
22/04/2019

POLIMORFISMO
Esto se debe a que una instancia de subclase posee todas las propiedades de su
superclase. Sin embargo, NO PUEDES invocar los métodos definidos en la clase de
Cilindro para la referencia c1, por ejemplo.

Esto se debe a que c1 es una referencia a la clase Circulo, que no conoce los
métodos definidos en la subclase Cilindro.

POLIMORFISMO
c1 es una referencia a la clase Circulo, pero contiene un objeto de su subclase
Cilindro. La referencia c1, sin embargo, conserva su identidad interna.
En nuestro ejemplo, la subclase Cilindro reemplaza los métodos getArea() y
toString().
c1.getArea() o c1.toString() invoca la versión anulada definida en la subclase
Cilindro, en lugar de la versión definida en Circulo. Esto se debe a que, de hecho, c1
contiene un objeto Cilindro internamente.

30
22/04/2019

POLIMORFISMO
Resumen
 Se puede asignar (sustituir) una instancia de subclase a una referencia de
superclase.
 Una vez sustituido, podemos invocar métodos definidos en la superclase; No
podemos invocar métodos definidos en la subclase.
 Sin embargo, si la subclase sobreescribe los métodos heredados de la
superclase, se invocarán las versiones de la subclase.

POLIMORFISMO. EJEMPLO
El polimorfismo es muy poderoso en la programación orientada a objetos para
separar la interfaz y la implementación.
Considera el siguiente ejemplo.
Supongamos que nuestro programa utiliza muchos tipos de formas, como triángulos,
rectángulos, etc. Deberíamos diseñar una superclase llamada Shape, que define las
interfaces públicas (o comportamientos) de todas las formas.
Por ejemplo, nos gustaría que todas las formas tengan un método llamado getArea(),
que devuelve el área de esa forma en particular. La clase de forma se puede
escribir de la siguiente manera.

31
22/04/2019

POLIMORFISMO. EJEMPLO

POLIMORFISMO. EJEMPLO

Ten en cuenta que tenemos un problema


al escribir el método getArea() en la
clase Shape, porque el área no se puede
calcular a menos que se conozca la forma
real.
Imprimiremos un mensaje de error por el
momento.
En la sección posterior, te mostraré cómo
resolver este problema. Luego podemos
derivar subclases, como Triángulo y
Rectángulo, a partir de la Forma de la
superclase.

32
22/04/2019

POLIMORFISMO. EJEMPLO
Las subclases sobrescriben el método getArea() heredado de la superclase y
proporcionan las implementaciones adecuadas para getArea().

POLIMORFISMO. EJEMPLO
En nuestra aplicación, podríamos crear referencias de Shape y asignarles instancias
de subclases de la siguiente manera:

33
22/04/2019

POLIMORFISMO. EJEMPLO
Los resultados esperados son:

La belleza de este código es que todas las referencias son de la superclase (es decir,
la programación en el nivel de interfaz).
Podrías crear instancias de subclases diferentes y el código aún funciona. Puede
extender su programa fácilmente agregando más subclases, como Círculo, Cuadrado,
etc., con facilidad.

POLIMORFISMO. EJEMPLO
No obstante, la definición anterior de la clase Shape plantea un problema, si alguien
crea una instancia de un objeto Shape e invoca getArea() desde el objeto Shape, el
programa se interrumpe.

Esto se debe a que la clase Shape está diseñada para proporcionar una interfaz
común a todas sus subclases, que se supone que proporcionan la implementación real.
No queremos que nadie cree una instancia de Shape. Este problema se puede
resolver utilizando la llamada clase abstracta.

34
22/04/2019

POLIMORFISMO. OTRO EJEMPLO

El polimorfismo es un mecanismo poderoso en OOP para separar la interfaz y la


implementación a fin de permitir que el programador programe en la interfaz en el
diseño de un sistema complejo

POLIMORFISMO. OTRO EJEMPLO


Por ejemplo, en nuestra aplicación de juego, tenemos muchos tipos de monstruos que
pueden atacar. Diseñaremos una superclase llamada Monster y definiremos el
método attack() en la superclase. Las subclases proporcionarán entonces su
implementación real. En el programa principal, declaramos instancias de superclase,
sustituidas por subclase real; e invocar el método definido en la superclase.

35
22/04/2019

POLIMORFISMO. OTRO EJEMPLO

UPCASTING Y DOWNCASTING
Upcasting (o conversión ascendente) de una instancia de subclase a una
referencia de superclase.
Sustituir una instancia de subclase por su superclase se llama "upcasting".
La conversión ascendente –upcasting- siempre es segura porque una instancia de
subclase posee todas las propiedades de su superclase y puede hacer lo que su
superclase puede hacer. El compilador comprueba si hay una conversión ascendente
válida y emite errores de "tipos incompatibles" de lo contrario. Por ejemplo,

36
22/04/2019

UPCASTING Y DOWNCASTING
Downcasting (conversión descendente) de una referencia sustituida a su clase original
Puede revertir una instancia sustituida de nuevo a una referencia de subclase. Esto se llama
"downcasting". Por ejemplo

El downcasting requiere un operador de conversión de tipo explícito en forma de operador


de prefijo (nuevo tipo).
El downcasting no siempre es seguro, y lanza una excepción ClassCastException en tiempo de
ejecución si la instancia que se va a reducir no pertenece a la subclase correcta. Un objeto de
subclase puede ser sustituido por su superclase, pero lo contrario no es cierto

UPCASTING Y DOWNCASTING. EJEMPLO

37
22/04/2019

UPCASTING Y DOWNCASTING. EJEMPLO


Operador de Casting
El compilador puede no detectar el error en la conversión explícita, se detectará solo
en tiempo de ejecución. Por ejemplo,

EL OPERADOR INSTANCEOF
Una instancia de subclase es también una instancia de su superclase. Por ejemplo,

38
22/04/2019

POLIMORFISMO
Resumen
 Una instancia de subclase procesa todas las operaciones de atributos de su superclase.
Cuando se espera una instancia de superclase, se puede sustituir por una instancia de
subclase. En otras palabras, una referencia a una clase puede contener una instancia de
esa clase o una instancia de una de sus subclases, se llama sustituibilidad.
 Si una instancia de subclase se asigna a una referencia de superclase, puede invocar los
métodos definidos en la superclase solamente. No puede invocar métodos definidos en la
subclase.
 Sin embargo, la instancia sustituida conserva su propia identidad en términos de métodos
sobreescritos y ocultando variables. Si la subclase sobreescribe los métodos de la superclase,
se ejecutará la versión de la subclase, en lugar de la versión de la superclase.

CLASES ABSTRACTAS
Métodos y clases abstractas
En los ejemplos anteriores de Shape y Monster, encontramos un problema cuando
creamos instancias de Shape y Monster y ejecutamos getArea() o attack(). Esto se
puede resolver a través de métodos abstractos y clases abstractas.

Un método abstracto es un método con solo cabecera (es decir, el nombre del
método, la lista de argumentos y el tipo de retorno) sin implementación (es decir, el
cuerpo del método). Utiliza la palabra clave abstract para declarar un método
abstracto.

39
22/04/2019

CLASES ABSTRACTAS
Por ejemplo, en la clase Shape, podemos declarar los métodos abstractos getArea(),
draw (), etc., de la siguiente manera:

La implementación de estos métodos NO es posible en la clase Shape, ya que la


forma real aún no se conoce. (¿Cómo calcular el área si no se conoce la forma?)
La implementación de estos métodos abstractos se proporcionará más adelante una
vez que se conozca la forma real. Estos métodos abstractos no pueden invocarse
porque no tienen implementación.

CLASES ABSTRACTAS
Una clase que contiene uno o más
métodos abstractos se llama una
clase abstracta.
Una clase abstracta debe ser
declarada con el modificador de
clase abstract.
Una clase abstracta NO PUEDE
ser instanciada, ya que su
definición no está completa.
Notación UML: la clase abstracta y
el método se muestran en cursiva.

40
22/04/2019

CLASES ABSTRACTAS. SHAPE Y SUS SUBCLASES


Reescribamos nuestra clase Shape como una clase abstracta, que contiene un método
abstracto getArea() de la siguiente manera:

CLASES ABSTRACTAS. SHAPE Y SUS SUBCLASES


Una clase abstracta está incompleta en su definición, ya que falta la implementación
de sus métodos abstractos. Por lo tanto, una clase abstracta no puede ser
instanciada. En otras palabras, no puede crear instancias de una clase abstracta (de
lo contrario, tendrá una instancia incompleta con el cuerpo del método faltante).
Para utilizar una clase abstracta, debe derivar una subclase de la clase abstracta.
En la subclase derivada, puede sobrescribir los métodos abstractos y proporcionar
la implementación a todos los métodos abstractos. Si no lo hace, la subclase debe ser
declarada como abstracta también.
La subclase derivada ahora está completa, y puede ser instanciada. (Si una subclase
no proporciona implementación a todos los métodos abstractos de la superclase, la
subclase permanece abstracta).

41
22/04/2019

CLASES ABSTRACTAS. SHAPE Y SUS SUBCLASES


Esta propiedad de la clase
abstracta resuelve nuestro
problema anterior.
En otras palabras, puede crear
instancias de las subclases como
Triángulo y Rectángulo, y hacer
upcast a Shape (para programar y
operar en el nivel de interfaz), pero
no puede crear instancia de Shape,
que evita el escollo que tenemos.
Por ejemplo,

CLASES ABSTRACTAS. SHAPE Y SUS SUBCLASES


En resumen, una clase abstracta proporciona una plantilla para un mayor desarrollo.
El propósito de una clase abstracta es proporcionar una interfaz común (o
protocolo, contrato, entendimiento o convención de nomenclatura) a todas sus
subclases.
Una clase abstracta sirve para desarrollar una jerarquía de clases en la que algún
comportamiento está presente en todas ellas pero se detalla en forma distinta en
cada una.

42
22/04/2019

CLASES ABSTRACTAS. SHAPE Y SUS SUBCLASES


Por ejemplo, en la clase abstracta Shape, puede definir métodos abstractos como
getArea() y draw(). Ninguna implementación es posible porque no se conoce la
forma real.
Sin embargo, al especificar la cabecera de los métodos como abstractos, todas las
subclases están obligadas a usar la cabecera de estos métodos. Las subclases
podrían proporcionar las implementaciones adecuadas.

CLASES ABSTRACTAS. SHAPE Y SUS SUBCLASES


Junto con el polimorfismo, se puede convertir instancias de subclases a Shape y
programar en el nivel Shape.
La separación de la interfaz y la implementación permite un mejor diseño del
software y una fácil expansión.
Por ejemplo, Shape define un método llamado getArea(), en el que todas las
subclases deben proporcionar la implementación correcta.
Puede solicitar un getArea() de cualquier subclase de Shape, se calculará el área
correcta. Además, tu aplicación se puede extender fácilmente para acomodar
nuevas formas (como Círculo o Cuadrado) al derivar más subclases.

43
22/04/2019

CLASES ABSTRACTAS.
Notas:
 Un método abstracto no puede ser declarado final, ya que el método final no
puede ser sobreescrito. Un método abstracto, por otro lado, debe ser sobreescrito en
un descendiente antes de que pueda ser utilizado.
 Un método abstracto no puede ser privado (lo que genera un error de
compilación). Esto se debe a que el método privado no es visible para la subclase y,
por lo tanto, no se puede sobreescribir.
 Si una clase contiene un método abstract, entonces la clase deberá ser declarada
como abstract forzosamente.
 Por el contrario una clase abstract no tiene por que tener métodos abstract
forzosamente.

CLASES ABSTRACTAS.
 las clases abstractas pueden tener constructores, pero SOLAMENTE para ser
usados desde los constructores de las clases hijas, no puedes usarlos directamente
porque por definición no se puede instanciar una clase abstracta.
 Un método abstract nunca podrá ser static.
 En definitiva abstract es sinónimo de genérico
La utilidad de las clases abstractas es crear clases genéricas o plantillas, cuya
funcionalidad será implementada por las subclases.
De esta manera, todas las subclases tendrán una interfaz común. Es decir funcionarán
con los mismos métodos y realizarán las mismas operaciones. Pero cada subclase
tendrá una funcionalidad interna diferente.

44
22/04/2019

CLASES ABSTRACTAS
Regla de oro: programa en la interfaz, no en la implementación.
(Es decir, haz referencias en la superclase; sustitúyelas por
instancias de subclase; invoca los métodos definidos solo en la
superclase).

ACTIVIDAD 10. CLASES ABSTRACTAS


Reescribe la Superclase Shape y sus subclases
Circle, Rectangle and Square, como se muestra en
el diagrama de la clase.
Enunciado disponible en el aula virtual

45
22/04/2019

ACTIVIDAD 11. POLIMORFISMO


Disponible en el aula virtual

CLASES Y MÉTODOS FINALES


Hasta ahora. La única herramienta que nos permite controlar si un método o
atributo se hereda o no es el modificador private.
 Si definimos un atributo o un método como private este no puede ser
heredado por ninguna subclase.
 Que ocurre si lo que queremos es permitir que si lo herede pero que no
pueda redefinirlo. Es decir que lo utilice tal y como aparece en la clase
padre.
 Para esto en java existe la palabra reservada final

46
22/04/2019

CLASES Y MÉTODOS FINALES


Cuando definimos un atributo como final lo que estamos haciendo es definir ese atributo como
constante. Por tanto estamos estableciendo su valor como fijo y este no se podrá modificar.
public static final pi=3,141592;
En el caso de aplicar final a un método, lo que estamos haciendo es permitir que este método
se herede pero obligando a mantener fija su funcionalidad, es decir que no se puede
redefinir.

En este caso ninguna clase que herede este método podrá redefinir su funcionalidad, solo
podrá invocarlo igual que en la clase padre.

CLASES Y MÉTODOS FINALES


También podemos definir una clase completa como final. Al definir una clase como
final, estamos impidiendo que ninguna clase pueda heredar de ella.

47
22/04/2019

INTERFACES
En JAVA sólo se puede heredar de una
única clase. En otros lenguajes como
smalltalk y C++ se puede heredar de
varias clases lo que se conoce como
herencia múltiple. Este tipo de herencia es
muy potente pero también es fuente de
incoherencias y errores.
Para solucionar esto en JAVA se definen
las interfaces, de forma que una clase
puede heredar de una única superclase
pero además implementar todas las
interfaces que desee.

INTERFACES
Pero entonces ¿Qué es una interfaz?
Una interfaz Java es una superclase abstracta al 100% que define un conjunto de
métodos que sus subclases deben soportar.
Una interfaz contiene solo métodos abstractos públicos (métodos con cabecera y
sin implementación) y posiblemente constantes (variables finales públicas estáticas).
Debe utilizar la palabra clave "interfaz" para definir una interfaz (en lugar de la
palabra clave "clase" para las clases normales). La palabra clave public y abstract
no son necesarias para sus métodos abstractos, ya que son obligatorios.

48
22/04/2019

INTERFACES
Similar a una superclase abstracta, una interfaz no puede ser instanciada. Debe
crear una "subclase" que implemente una interfaz y proporcionar la implementación
real de todos los métodos abstractos.
A diferencia de una clase normal, donde se usa la palabra clave “extends" para
derivar una subclase. Para la interfaz, usamos la palabra clave “implements" para
derivar una subclase.
Una interfaz es un contrato para lo que las clases pueden hacer. Sin embargo, no
especifica cómo deben hacerlo las clases.

INTERFACES
Una interfaz proporciona una forma, un protocolo, un estándar, un contrato, una
especificación, un conjunto de reglas, una interfaz, para todos los objetos que la
implementan. Es una especificación y reglas que cualquier objeto que lo
implemente se compromete a seguir.

En Java, la clase abstracta y la interfaz se utilizan para separar la interfaz pública


de una clase de su implementación para permitir que el programador programe en
la interfaz en lugar de las diferentes implementaciones.

49
22/04/2019

INTERFACES
Convención de nomenclatura de interfaz: usa un adjetivo (normalmente termina con
“able") que consiste en una o más palabras. Cada palabra debe tener mayúscula
inicial (camell case).
Por ejemplo,
Serializable, Extenalizable, Movible, Clonable, Ejecutable, etc.

ACTIVIDAD 12
La interface de Shape y sus implementaciones.
Podemos volver a escribir la superclase abstracta
como una interfaz, que contiene solo métodos
abstractos, como muestra la figura

Notación UML: clases abstractas, interfaces y


métodos abstractos se muestran en cursiva. La
implementación de la interfaz está marcada por
una flecha de guiones que va desde las subclases
a la interfaz.

50
22/04/2019

ACTIVIDAD 12

INTERFACES
 Una interfaz es un tipo de clase especial en la que no se implementa ninguno de
sus métodos, todos son abstractos (una clase abstracta podía implementarlos o no).
Además en una interfaz sólo se pueden definir atributos constantes.
 Una interfaz sólo define los métodos que se van a utilizar, que parámetros reciben y
que tipo de dato devuelven. Dejando libertad para implementar la funcionalidad
en cada una de las clases que implementan la interfaz.
 Cuando se “hereda” de una interfaz, se dice que se implementa dicha interfaz, ya
que no se hereda ninguna funcionalidad, sino que se lo que se va a hacer es
implementar los métodos de esta.
 Cuando se implementa una interfaz, hay que implementar todos sus métodos o
declarar la clase como abstracta.

51
22/04/2019

INTERFACES. INTERFAZ MOVABLE Y SU


IMPLEMENTACIÓN
Supongamos que nuestra aplicación involucra muchos objetos que se pueden mover.
Podríamos definir una interfaz llamada Movable, que contiene las cabeceras de los
distintos métodos de movimiento.

INTERFACES. INTERFAZ MOVABLE Y SU


IMPLEMENTACIÓN

Similar a una clase abstracta, una interfaz no puede ser instanciada; porque está
incompleta (falta el cuerpo de los métodos abstractos).
Para usar una interfaz, nuevamente, debe derivar subclases y proporcionar
implementación a todos los métodos abstractos declarados en la interfaz. Las
subclases ahora están completas y pueden ser instanciadas.

52
22/04/2019

INTERFACES. INTERFAZ MOVABLE Y SU


IMPLEMENTACIÓN
Para derivar subclases de una interfaz, se
debe utilizar la palabra clave
“implements" en lugar de “extends" para
derivar subclases de una clase ordinaria o
una clase abstracta.
Es importante tener en cuenta que la
subclase que implementa una interfaz
debe sobrescribir TODOS los métodos
abstractos definidos en la interfaz; de lo
contrario, la subclase no puede ser
compilada.

INTERFACES. INTERFAZ MOVABLE Y SU


IMPLEMENTACIÓN
Otras clases en la aplicación pueden igualmente implementar la interfaz de Movable
y proporcionar su propia implementación a los métodos abstractos definidos en la
interfaz de Movable.

53
22/04/2019

INTERFACES. INTERFAZ MOVABLE Y SU


IMPLEMENTACIÓN
También podemos enviar instancias de subclases a la interfaz de Movable, a través
del polimorfismo, de forma similar a una clase abstracta.

IMPLEMENTANDO MÚLTIPLES INTERFACES


Como se mencionó, Java solo admite herencia simple. Es decir, una subclase
puede derivarse de una y solo una superclase.
Java no admite la herencia múltiple para evitar la herencia de propiedades
en conflicto de varias superclases. La herencia múltiple, sin embargo, tiene su
lugar en la programación.

54
22/04/2019

IMPLEMENTANDO MÚLTIPLES INTERFACES


Sin embargo, una subclase puede implementar más de una interfaz. Esto está
permitido en Java, ya que una interfaz simplemente define los métodos abstractos sin
las implementaciones reales y es menos probable que conduzca a heredar
propiedades en conflicto de varias interfaces.
En otras palabras, Java soporta indirectamente múltiples herencias a través de la
implementación de múltiples interfaces. Por ejemplo,

INTERFACES
La sintaxis formal para declarar interfaz es:

55
22/04/2019

INTERFACES
Todos los métodos en una interfaz serán públicos y abstractos (por defecto).
No puede usar otro modificador de acceso, como privado, protegido y
predeterminado, o modificadores, como static , final.
Todos los campos serán públicos, estáticos y finales (por defecto).
Una interfaz puede "extenderse" desde una super-interfaz.

INTERFACES
Notación UML: la notación UML utiliza una flecha de línea continua que une la
subclase con una superclase concreta o abstracta, y la flecha de línea discontinua con
una interfaz como se ilustra. La clase abstracta y el método abstracto se muestran en
cursiva.

56
22/04/2019

¿POR QUÉ INTERFACES?


Una interfaz es un contrato (o un protocolo, o un entendimiento común) de lo que
pueden hacer las clases. Cuando una clase implementa una determinada interfaz,
se compromete a proporcionar implementación a todos los métodos abstractos
declarados en la interfaz.
La interfaz define un conjunto de comportamientos comunes. Las clases implementan
la interfaz de acuerdo con estos comportamientos y proporcionan su propia
implementación a los comportamientos.

¿POR QUÉ INTERFACES?


Esto le permite programar en la interfaz, en lugar de la implementación real.
Uno de los principales usos de la interfaz es proporcionar un contrato de
comunicación entre dos objetos. Si sabe que una clase implementa una interfaz,
entonces sabe que la clase contiene implementaciones concretas de los métodos
declarados en esa interfaz, y se le garantiza que podrá invocar estos métodos de
manera segura.
En otras palabras, dos objetos se pueden comunicar según el contrato definido en
la interfaz, en lugar de su implementación específica.

57
22/04/2019

¿POR QUÉ INTERFACES?


En segundo lugar, Java no admite la herencia múltiple (mientras que C ++ sí lo hace).
La herencia múltiple le permite derivar una subclase de más de una superclase
directa. Esto plantea un problema si dos superclases directas tienen implementaciones
conflictivas. (¿Cuál seguir en la subclase?).
Sin embargo, la herencia múltiple tiene su lugar. Java hace esto permitiéndole
"implementar" más de una interfaz.

INTERFACE VS SUPERCALSE ABSTRACTA


¿Cuál es un mejor diseño: interfaz o superclase abstracta? No hay una respuesta
clara.
Utiliza la superclase abstracta si hay una jerarquía de clases clara. La clase
abstracta puede contener implementación parcial (como variables de instancia y
métodos). La interfaz no puede contener ninguna implementación, sino que
simplemente define los comportamientos.

58
22/04/2019

ACTIVIDAD 13

ACTIVIDAD 14

59
22/04/2019

RESUMEN
 Utilizaremos una clase que no herede de nadie cuando la clase no cumpla la
condición de es-un para el problema a resolver.
 Utilizaremos una subclase cuando sea la relación e especialización es-un de
la superclase mediante la sobrescritura o añadiendo nuevos metodosy/o
atributos para el problema a resolver
 Utilizaremos una clase final cuando queramos impedir que otras clases
puedan heredar de esta.
 Utilizaremos métodos finales cuando queramos permitir la herencia pero no
permitamos redefinir el método.

RESUMEN
 Utilizaremos una clase abstracta cuando se quiera definir un grupo genérico
de clases que compartan algunos métodos implementados que reutilizar.
También cuando queramos que nadie pueda crear objetos de dicha clase.
 Utilizaremos una interfaz cuando se quiera definir un grupo genérico de
clases y no existan métodos implementados que reutilizar. O cuando nos
veamos forzados a heredar de más de una clase.

60
22/04/2019

LA INTERFACE COMPARABLE

EL TIPO DEL PARÁMETRO DE COMPARABLE

61
22/04/2019

EJEMPLO DE COMPARABLE

USO DE COMPARETO PARA ORDENAR

62
22/04/2019

DISEÑO ORIENTADO A OBJETOS


En el diseño orientado a objetos, es deseable diseñar
clases que estén estrechamente encapsuladas, poco
acopladas y altamente cohesivas, de modo que las
clases sean fáciles de mantener y adecuadas para su
reutilización.

DISEÑO ORIENTADO A OBJETOS.


ENCAPSULAMIENTO
El encapsulamiento se refiere a mantener los datos y métodos dentro de una clase
tal que los usuarios no accedan a los datos directamente, sino a través de los
métodos públicos.
Se desea una estrecha encapsulación, que se puede lograr declarando que todas
las variables privadas y proporcionando getters y setters públicos a ellas.
El beneficio es que tiene un control completo sobre cómo deben leerse los datos (por
ejemplo, en qué formato) y cómo se deben cambiar los datos (por ejemplo, la
validación).
Ejemplo: Clase Tiempo con variables privadas hora (0-23), minuto (0-59) y segundo
(0-59); getters y setters (lanza IllegalArgumentException).

63
22/04/2019

DISEÑO ORIENTADO A OBJETOS.


ENCAPSULAMIENTO
Ocultamiento de la información: otro beneficio clave del estrecho
encapsulamiento es el ocultamiento de la información, lo que
significa que los usuarios no son conscientes (y no necesitan saber)
de cómo se almacenan los datos internamente.

DISEÑO ORIENTADO A OBJETOS. ACOPLAMIENTO


El acoplamiento se refiere al grado en que una clase se basa en
el conocimiento de los aspectos internos de otra clase.
El acoplamiento alto no es deseable porque si una clase cambia
sus representaciones internas, todas las demás clases con
acoplamiento alto deben reescribirse.
Claramente, el acoplamiento bajo a menudo se asocia con un
estrecho encapsulamiento. Por ejemplo, un método público bien
definido para acceder a los datos, en lugar de acceder
directamente a los datos.

64
22/04/2019

DISEÑO ORIENTADO A OBJETOS. COHESIÓN


La cohesión se refiere al grado en que una clase o método se resiste a
dividirse en partes más pequeñas.
Alto grado de cohesión es deseable.
Cada clase se diseñará para modelar una sola entidad con su conjunto de
responsabilidades y realizar una recopilación de tareas estrechamente
relacionadas; y cada método cumplirá una sola tarea.
Las clases de baja cohesión son difíciles de mantener y reutilizar. Ejemplo de
baja cohesión: Libro y Autor en una clase, o Coche y Conductor en una clase.

DISEÑO ORIENTADO A OBJETOS. COHESIÓN


Una vez más, la alta cohesión está asociada con el acoplamiento
bajo. Esto se debe a que una clase altamente cohesiva tiene menos
interacciones (o mínimas) con otras clases.

65
22/04/2019

DISEÑO ORIENTADO A OBJETOS.

RECURSOS
 Curso youtube : Java desde 0
 Libro Java 9. Manual imprescindible. F. Javier Moldes Teo. Editorial Anaya
 App SoloLearn: Aprende a Programar. Curso Java

66

También podría gustarte