Title: Programaci
1Programación Orientada a Objetos en Java
- Unidad 3
- Herencia y Polimorfismo
2Temario
- Herencia
- Reescritura de métodos
- Polimorfismo
- Clases abstractas
- Interfaces
3Herencia
- 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
4Herencia 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
5Ejemplo
- class Figura
- int x, y
- public void print() ...
- public void setX(int x) this.x x
- public void setY(int y) this.y y
-
- 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)
- r.setAncho(100) r.setLargo(300)
-
- La clase Circulo es derivada de la clase base
Figura
- La clase Circulo hereda métodos setX y setY de
clase base Figura
6Encapsulamiento
- 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
7Polimorfismo
- 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
8Polimorfismo
circulo new Circulo()
Figura figura
figura circulo
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
9Polimorfismo
- 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())
10Reescritura 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
11Reescritura 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
12Dynamic 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
13Compatibilidad 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
14Identificació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)
15Constructor 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)
- ...
-
- ...
16Ejemplo
- 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
17Ejemplo 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
18Consideraciones 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()?
19Clases 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()
-
- public class Carta extends Documento
- public void print()
- ...
-
-
- Una subclase de una clase abstracta debe
- implementar todos los métodos abstractos
heredados, o bien - ser a su vez declarada abstracta
- Clase Documento es abstracta si se intenta
instanciarla, se produce un error de compilación
- Si la clase Carta no provee una implementación
del método print(), se produce un error de
compilación
20Java 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
21Interfaces
- 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
22Interfaces
- 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
23Interfaces
- 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
24Definiendo una Interfaz
interface Printable int PORTRAIT 0int
LANDSCAPE 1 void print(int orientacion)
- Campos son automáticamente public final static
- Métodos son automáticamente public abstract
25Implementando 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) ...
26Usando 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)
27Resumen
- 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
28Resumen
- 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