Download Java3-Herencia

Document related concepts
no text concepts found
Transcript
Programación Orientada a
Objetos en Java
Unidad 3
Herencia y Polimorfismo
Temario





Herencia
Reescritura de métodos
Polimorfismo
Clases abstractas
Interfaces
2
Herencia


In object-oriented programming (OOP), Inheritance is a way to
compartmentalize and reuse code by creating collections of
attributes and behaviors called objects which can be based on
previously created objects. In classical inheritance where
objects are defined by classes, classes can inherit other classes.
The new classes, known as Sub-classes (or derived classes),
inherit attributes and behavior of the pre-existing classes, which
are referred to as Super-classes (or ancestor classes). The
inheritance relationship of sub- and superclasses gives rise to a
hierarchy. In Prototype-based programming objects can be
defined directly from other objects without the need to define
any classes.
The inheritance concept was invented in 1967 for Simula.
Wikipedia
3
Herencia en Java




Todas las clases son descendientes de la clase Object
La cláusula extends especifica el ancestro inmediato
de la clase
Una subclase o clase derivada hereda todos los
campos y métodos de la superclase o clase base
Java soporta herencia simple (sólo una clase base)
ancestro
superclase
clase base
"hereda de"
"extiende"
"is a"
descendientes
subclases
clases derivadas
4
Ejemplo
class Figura {
int x, y;
public void print() { ... }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
}
La clase Circulo es derivada de la
clase base Figura

class Rectangulo extends Figura {
int largo, ancho;
public void setLargo(int largo) { this.largo = largo; }
public void setAncho(int ancho) { this.ancho = ancho; }
}
class App {
void f() {
Rectangulo r = new Rectangulo();
r.setX(10); r.setY(20);
La clase Circulo hereda métodos
setX y setY de clase base Figura

r.setAncho(100); r.setLargo(300);
}
}
5
Encapsulamiento



Una clase derivada tiene acceso a los
miembros public y protected de una clase
base, aunque pertenezcan a paquetes
diferentes
Una clase derivada tiene acceso a los
miembros package de una clase base si
ambas clases pertenecen al mismo paquete
Una clase derivada no tiene acceso a los
miembros private de una clase base
6
Polimorfismo


Polymorphism, in the context of object-oriented
programming, is the ability of one type, A, to appear
as and be used like another type, B. The purpose of
polymorphism is to implement a style of
programming called message-passing in the
literature, in which objects of various types define a
common interface of operations for users.
In strongly typed languages, polymorphism usually
means that type A somehow derives from type B, or
type C implements an interface that represents type
B. In weakly typed languages types are implicitly
polymorphic.
Wikipedia
7
Polimorfismo
Circulo circulo;
circulo = new Circulo();
Figura figura;
circulo
figura = circulo;
figura
Compila y ejecuta bien (un círculo es una figura)
Restricción: no se puede usar figura para acceder a
métodos especializados de Circulo
figura.getRadio(); // no compila
8
Polimorfismo

Java permite asignar un objeto a una
variable declarada con un tipo de datos
ancestro
void metodo1(Figura f) {
f.print();
...
}
void metodo2() {
metodo1(new Circulo());
}
9
Reescritura de Métodos

Method overriding, in object oriented programming, is a
language feature that allows a subclass or child class to provide
a specific implementation of a method that is already provided
by one of its superclasses or parent classes. The implementation
in the subclass overrides (replaces) the implementation in the
superclass by providing a method that has same name, same
parameters or signature, and same return type as the method in
the parent class.The version of a method that is executed will
be determined by the object that is used to invoke it. If an
object of a parent class is used to invoke the method, then the
version in the parent class will be executed. If an object of the
subclass is used to invoke the method, then the version in the
child class will be executed.
Wikipedia
10
Reescritura de Métodos
public class DTE {
...
public void validar() {
...
}
}
public class Factura extends DTE
public void validar() {
super.validar();
...
}
}
{
Reescritura del método validar() en
clase derivada (la firma y el tipo de
retorno coinciden con los de la clase
base)

Invocación a funcionalidad provista
en la clase base, para extender en
lugar de reemplazar

11
Dynamic Binding


Al invocar un método no static, el tipo real
del objeto sobre el que se invoca el método
— y no el tipo de la referencia — es utilizado
para determinar qué versión del método
invocar
El tipo del objeto sobre el que se invoca el
método se obtiene en tiempo de ejecución,
por eso esta funcionalidad recibe el nombre
de dynamic binding, o late binding
void procesarDTE(DTE dte) {
dte.validar();
Dynamic binding: invoca a
...
Factura.validar() si dte es una
}
referencia a una Factura
12
Compatibilidad de Tipos

Java es fuertemente tipeado, exige
compatibilidad de tipos en tiempo de
compilación:


Permite asignar un objeto a una variable de un
tipo ancestro
Permite asignar un objeto a una variable de un
tipo descendiente, pero exige que se explicite este
uso, mediante un cast (si el cast falla en
ejecución, la máquina virtual lanza un
ClassCastException)
Factura factura = (Factura) dte;

No permite realizar una conversión de un objeto a
un tipo que no es ancestro ni descendiente
13
Identificación de Tipo


El método getClass de la clase Object retorna un
objeto de tipo Class correspondiente a la clase real a
la que pertenece el objeto
El operador instanceof indica si un objeto es de una
clase determinada o de alguna clase descendiente
if (dte instanceof Factura) {
Factura factura = (Factura) dte;
// uso de factura
}
Ojo, no abusar de este mecanismo!
(hacerlo significa que se está programando
de manera tradicional, sin obtener los
beneficios de la OOP)

14
Constructor en Subclases

El constructor de una subclase debe invocar algún
constructor de la clase base:


Explícitamente: usando base()
Implícitamente: si no se invoca el constructor de la clase
base explícitamente, se invoca el constructor default
class DTE {
DTE(Empresa emisor, int folio) { ... }
...
}
class Factura extends DTE {
Factura(Empresa emisor, int folio, Empresa receptor) {
super(emisor, folio);
...
}
...
}
15
Ejemplo


Se desea construir una aplicación que
permita manejar múltiples ventanas,
con diferentes tipos de documentos:
cartas, memos, etc.
El sistema debe permitir que se imprima
la ventana activa, mediante la opción
de menú File/Print
16
Ejemplo: Diseño con Polimorfismo
public class Documento {
public void print() {...}
}
public class Carta extends Documento {
public void print() {...}
}
public class Memo extends Documento {
public void print() {...}
}
public class MiAplicacion {
public void print() {
Window w = GUI.getCurrentWindow();
Documento d = obtenerDocumento(w);
d.print();
Dynamic binding: se invoca al método print
}
implementado en la clase del objeto referenciado por la
}
variable d, el cual se determina en ejecución
17
Consideraciones de Diseño


Supongamos que en el diseño anterior, la clase
Documento no debe instanciarse, sólo se ha creado
para construir una jerarquía de clases y hacer uso de
los mecanismos de polimorfismo y dynamic binding;
¿cómo impedir que por error se instancie la clase
Documento?
Supongamos que en el diseño anterior las clases
derivadas de Documento deben proveer una
implementación del método print() (no tiene sentido
programar una implementación default en la clase
Documento); ¿cómo obligar a las clases derivadas a
proveer una implementación del método print()?
18
Clases Abstractas



Una clase abstracta no puede ser instanciada
Puede contener métodos abstractos, a ser implementados en
subclases
Puede contener métodos concretos
public abstract class Documento {
...
public abstract void print();
}
Clase Documento es
abstracta: si se intenta
instanciarla, se produce un
error de compilación

public class Carta extends Documento {
public void print() {
Si la clase Carta no provee
...
una implementación del
}
método print(), se produce un
}
error de compilación

Una subclase de una clase abstracta debe:


implementar todos los métodos abstractos heredados, o bien
ser a su vez declarada abstracta
19
Java No Soporta Herencia Múltiple



En ocasiones es útil que una clase se pueda ver de
varias formas, utilizando polimorfismo
En C++, lo anterior se implementa con herencia
múltiple, pero esto genera problemas cuando se
hereda implementación
Para evitar estos problemas, Java no soporta
herencia múltiple, pero sí permite que una clase
implemente múltiples interfaces
20
Interfaces


In object-oriented languages the term interface is
often used to define an abstract type that contains
no data, but exposes behaviors defined as methods.
A class having all the methods corresponding to that
interface is said to implement that interface
(furthermore a class can implement multiple
interfaces, and hence can be of different types at the
same time).
An interface is hence a type definition; anywhere an
object can be exchanged (in a function or method
call) the type of the object to be exchanged can be
defined in terms of an interface instead of a specific
class. This allows later code to use the same function
exchanging different object types; hence such code
turns out to be more generic and reusable.
Wikipedia
21
Interfaces


An interface is a kind of classifier that represents a
declaration of a set of coherent public features and
obligations. An interface specifies a contract; any
instance of a classifier that realizes the interface must
fulfill that contract.
Since interfaces are declarations, they are not
instantiable. Instead, an interface specification is
implemented by an instance of an instantiable
classifier, which means that the instantiable classifier
presents a public facade that conforms to the
interface specification. Note that a given classifier
may implement more than one interface and that an
interface may be implemented by a number of
different classifiers.
UML Specification 2.0
22
Interfaces







Una interfaz (interface) es una colección de métodos
abstractos y constantes
Una interfaz no puede ser instanciada
Una clase que implementa una interfaz debe
implementar los métodos declarados en ella
Una clase puede implementar múltiples interfaces
Una interfaz define un tipo de datos que se puede
utilizar en la declaración de variables
Una variable declarada mediante una interfaz puede
referenciar un objeto de alguna clase que
implemente la interfaz
Java soporta herencia múltiple de interfaces
23
Definiendo una Interfaz
interface Printable {
int PORTRAIT = 0;
int LANDSCAPE = 1;
void print(int orientacion);
}


Campos son automáticamente public
final static
Métodos son automáticamente public
abstract
24
Implementando una Interfaz
class Libro extends Documento implements Printable {
public void print(int orientacion) {
// implementación
}
}
class Empleado implements Printable {
public void print(int orientacion) { ... }
}
class Rectangulo implements Printable {
public void print(int orientacion) { ... }
}
25
Usando una Interfaz

Capa genérica
class ColaImpresion {
static void creaJob(Printable p) {
…
p.print(Printable.PORTRAIT);
}
}

Capa cliente
ColaImpresion.creaJob(new Empleado(…));
ColaImpresion.creaJob(new Rectangulo(…));
Libro libro = new Libro();
…
ColaImpresion.creaJob(libro);
26
Resumen



Herencia es un concepto de OOP mediante el
cual una clase adquiere las propiedades y los
métodos de otra
Una variable de un tipo de datos ancestro
puede ser utilizada para referenciar una
instancia de una clase descendiente
Al invocar sobre un objeto un método de
instancia que ha sido redefinido en subclases,
la máquina virtual invoca el método definido
en la clase real del objeto, obtenida en
tiempo de ejecución
27
Resumen





Una clase abstracta (abstract) puede
contener métodos abstractos
Una interfaz (interface) es una colección de
métodos abstractos y constantes
Las clases abstractas y las interfaces no
pueden ser instanciadas
Una clase puede extender a una clase, e
implementar un número ilimitado de
interfaces
Si una clase define o hereda métodos
abstractos, debe ser declarada abstracta
28