POO JAVA
Interface
Recordamos….
Definición de clases.
➢ Cada clase tiene un nombre y está compuesta por
Atributos y métodos.
➢ Cada instancia (‘variable’) de esa clase se denomina
objeto.
➢ Métodos: constructores(), set(), get(), toString()…..
➢ Para ejecutar un método, el objeto recibe un mensaje
Recordamos: Herencia
➢ La herencia en Java es una característica de la POO que
permite que una clase padre transfiera sus funciones y sus
atributos a clases hijas.
➢ La subclase (clase hijo/nieto…) ‘hereda’ todo de la clase padre
o super clase y puede (o no) agregar atributos y métodos.
➢ En Java sólo existe la Herencia simple (se hereda de 1 clase )
➢ El constructor de la clase hija refina el comportamiento del padre.
➢ En Java los constructores no se heredan La primera sentencia del
constructor de la clase hija SIEMPRE es una llamada al constructor
de la clase padre.
Recordamos: Modificadores de Acceso
MODIFICADORES DE ACCESO EN JAVA
El acceso a los atributos y métodos se determina mediante las
palabras reservadas de los modificadores de acceso, en Java
hay cuatro modificadores de acceso que definen ámbitos de
visibilidad de más restrictivos a menos restrictivos:
• private: únicamente la clase puede acceder a la propiedad o
método.
• package private (valor por defecto si no se indica ninguno):
solo las clases en el mismo paquete pueden acceder a la
propiedad o método.
• protected: las clases del mismo paquete y las clases que
heredan la clase pueden acceder a la propiedad o método.
• public: la propiedad o método es accesible desde cualquier
método de otra clase.
Recordamos: visibilidad
Ambitos de visibilidad
Los ámbitos de visibilidad según el modificador de acceso y el
origen de acceso a la propiedad o método son los siguientes.
Modificador de acceso Misma clase Clase en el mismo Clase que hereda en
paquete otro paquete
private Si NO NO
Sin modificador (por Si SI NO
defecto)
protected Si SI SI
public SI SI SI
Recordamos: visibilidad
En el gráfico que sigue hay
representados paquetes que
contienen clases, clases con
rectángulos, las flechas indican
herencia entre clases y las
clases que están coloreadas
indican que tienen visibilidad
de la propiedad y método
según el ámbito de acceso, la
ubicación de la clase que
accede y si hay una relación
de herencia. En esencia es la
misma información de la tabla
pero representada de forma
gráfica.
Recordamos: redefinición
➢ Al heredar es posible redefinir los métodos para adaptarlos a la
semántica de la nueva clase.
➢ Los atributos no se pueden redefinir, sólo se ocultan: si la clase hija
define un atributo con el mismo nombre que un atributo de la clase
padre, éste no está accesible (el campo de la superclase todavía
existe, pero no se puede acceder)
➢ Un método de la subclase con la misma signatura (nombre y
parámetros) que un método de la superclase lo está redefiniendo. Si
se cambia el tipo de los parámetros se está sobrecargando el método
original
➢ En Java se puede aplicar el modificador final a un método para
indicar que no puede ser redefinido.
➢ Asimismo, el modificador final es aplicable a una clase indicando
que no se puede heredar de ella.
Recordamos: polimorfismo
El término polimorfismo significa que hay un
identificador (variable, función o clase) y muchos
significados diferentes (distintas definiciones).
Formas de polimorfismo:
➢ Polimorfismo de asignación (variables polimorfas)
➢ Polimorfismo puro (función polimorfa)
➢ Polimorfismo ad hoc (sobrecarga)
➢ Polimorfismo de inclusión (redefinición)
➢ Polimorfismo paramétrico (genericidad)
Recordamos: polimorfismo
Polimorfismo de herencia:
Objetos de distintas clases de una misma
familia entienden los mismos mensajes.
Es la capacidad que tienen los objetos de
comportarse de diferentes formas.
Ejemplo 1 :
public static void main(String[] args) {
B objb1= new B(…); // invoca constructor
String x=”Hola”;
int y=10;
objb1.f1(x) // clase B
objb1.f1(x,y) // clase A
}
obj1 hereda de clase A
El método f1 está sobrecargado
(redefinido sin “tapar” al del padre).
Recordamos: polimorfismo
Ejemplo 2:
public static void main(String[] args)
{ B objb1= new B(…); //invoca constructor
String x=”Hola”;
int y=10;
objb1.f1(x) // clase B
}
El método f1 está redefinido “anulando”
o superponiéndose al del padre (tienen
igual signatura ).
Recordamos: polimorfismo
MÉTODOS POLIMÓRFICOS
SOBRECARGA (Polimorfismo ad-hoc)
Dos o mas funciones comparten el nombre y tienen distintos argumentos
(nro y tipo). La versión a ejecutar se determina en tiempo de compilación
(ligadura estática).
REDEFINICIÓN/OVERRIDING (Polimorfismo de inclusión)
Una o más funciones sobreescriben funciones de sus superclases con igual
nombre y argumentos (nro y tipo). La versión a ejecutar se determina en
tiempo de ejecución (ligadura dinámica).
FUNCIÓN POLIMORFA
Función polimorfa / Polimorfismo paramétrico (Polimorfismo puro)
Un método no sobreescrito con argumento/s de tipo objeto, puede ser
invocado con argumento/s de la misma clase de (los) parámetro(s)
formal(es)o con subclase(s) de la(s) misma(s)
Recordamos: polimorfismo
🠶Porqué es importante el polimorfismo?
Porque nos permite definir estructuras HETEROGENEAS
Texto [] Biblio; // arreglo con tipo base Texto
if (Biblio[3] instanceof Texto) then ... // True
if (Biblio[3] instanceof Apunte) then ... // True
if (Biblio[3] instanceof Visual) then ... // True
Recordamos: compatibilidad de tipos
Compatibilidad de tipos:
➢ B es compatible con A sólo si la clase B es descendiente de la clase
A (los hijos, nietos, son compatibles con los padres).
➢ Una asignación polimórfica es válida sólo si el tipo estático
(TipoEstatico) de la parte izquierda es superclase de la parte
derecha (TipoDinamico).
TipoEstatico obj = new TipoDinamico();
➢ El paso de parámetros es válido sólo si el tipo del parámetro reales
compatible con el tipo del parámetro formal.
➢ El TipoDinamico debe tener igual o mayor cantidad de memoria
que el TipoEstatico.
Casting
Ejemplo:
Text Tex1 = new Texto();
Libro Lib1= new Libro(cod, nom, aut, edit, isbn);
Tex1= Lib1;
[Link]();
[Link]();
Tex1 comienza a buscar en su tipo estático (si no lo encuentra,
intenta buscar hacia arriba ‘padre’), pero no tiene padre.
NUNCA BUSCA HACIA ABAJO
SOLUCIÓN: CASTING EXPLÍCITO
( (Libro) Tex1). GetISBN(); ☺
Casting
➢ Si el método es estático (NO Polimórfico), por ejemplo: getISBN(); el
objeto receptor del mensaje busca desde su tipo estático hacia
arriba o hace un CASTING EXPLÍCITO al tipo dinámico.
➢ Si el método es Polimórfico, por ejemplo: toString(); el objeto
receptor del mensaje comienza a buscar el método desde el tipo
dinámico.
EJEMPLO:
[Link](“ISBN: “ + [Link]());
[Link]("ISBN: " + ((Libro)Tex1).getISBN()); ☺
[Link]([Link]()); ☺
Clases abstractas e Interface
Polimorfismo:
Objetos de distintas clases de una misma familia entienden los mismos
mensajes.
Es la capacidad que tienen los objetos de comportarse de
diferentes formas. Un mismo mensaje puede provocar la invocación
de métodos distintos.
Se retarda la decisión sobre el método a llamar hasta el
momento en que vaya a ser utilizado (ejecución).
Objetivo:
➢Reutilización y flexibilidad.
¿Cómo se consigue?
➢Métodos polimórficos
➢Clases abstractas
➢Interfaces
Clases Abstractas
Una Clase Abstracta es una clase que no puede ser
instanciada directamente y está diseñada para ser heredada
por otras clases. Su propósito es proporcionar una base
común y definir un modelo o estructura que las clases
derivadas deben seguir.
Una Clase Abstracta sirve como plantilla a nivel de
comportamiento y propiedades sobre una Jerarquía de clases
completa.
A nivel conceptual las clases abstractas definen qué puede
hacer un conjunto de clases relacionadas.
Clases Abstractas
➢ No pueden ser instanciadas
➢ Solamente pueden crearse subclases
➢ Si la clase tiene al menos un método abstracto entonces debe ser
abstracta.
➢ Una clase abstracta puede no contener métodos abstractos.
➢ Un método abstracto es aquel del cual no se provee
implementación.
Ejemplo:
clase FiguraGeometrica que puede tener el atributo Origen (X,Y) y
métodos área() y perímetro(); pero la clase FiguraGeometrica no se
puede instanciar o crear un objeto de ella ya que lo que existe es:
Cuadrado, Rectángulo, Círculo. No tiene sentido crear objetos de
clase FiguraGeometrica.
Clase abstracta
Ejemplo:
public abstract class FiguraGeometrica
{private int x=0;
private int y=0; // puede no contener atributos
//NO TIENE CONSTRUCTOR
public abstract double area(); métodos abstractos no se
public abstract double perimetro(); } implementan
public class Cuadrado extends FiguraGeometrica
{private double base;
public Rectangulo (double b){base=b; } //constructor con argumento
public double area(){ return (base*base); }
public void perimetro() { .... } }
Métodos y Clases Final
Si no quiero que una clase pueda definir subclases de ésta la puede
declarar como final.
final class Ultimoelem{
………..}
En este caso:
Class Otroelem extends Ultimoelem{ …}//Error de compilación
De manera similar si no queremos que las subclases sobreescriban
algún método de la super clase debo declarar un método final.
final public double imprime() { …… }
Las subclases no pueden redefinir el método imprime().
Interfaces
Las interfaces son útiles para:
▪ capturar similitudes entre clases no relacionadas sin
forzar una relación entre ellas.
▪ declarar métodos que una o varias clases necesitan
implementar.
Una interface es una colección de definiciones de
métodos (sin implementaciones) y de valores constantes.
Las interfaces se utilizan para definir un protocolo de
comportamiento que puede ser implementado por
cualquier clase.
Interfaces
➢ No se pueden heredar atributos desde una interface.
➢ No se pueden heredar implementaciones de métodos
desde una interface.
➢ La herencia de una interface es independiente de la
herencia de la clase, las clases que implementan la
misma interface pueden o no estar relacionadas a
través del árbol de clases.
➢ Las interfaces NO implementan la herencia múltiple
Definición de interface
Para crear un Interface, se debe escribir tanto la
declaración como el cuerpo de la interface.
declaraciondeInterface {
cuerpodeInterface
}
Por convención el nombre de la interface empieza
con mayúscula.
Ejemplo de Interface
interface Coleccion {
void añadir(Object obj);
void borrar(Object obj); Cuerpo
Object buscar(Object obj); de la interface
int contadorActual();
}
La interface puede ser implementado por cualquier clase
que represente una colección de objetos
Jerarquía de Interfaces
➢ Una interface puede extender una o mas interface
➢ Una interface no puede extender una clase.
➢ Los métodos de una interface no se implementan
en la misma sino por otra clase.
➢ Si se quiere permitir el acceso a la interface fuera
del paquete se debe colocar el modificador de acceso
public.
Herencia de Interfaces
Ejemplo:
interface A { void funcA(); }
interface B extends A { void funcB(); }
class C implements B {
public void funcA() { [Link]("This is funcA"); }
public void funcB() { [Link]("This is funcB"); }}
public class Demo {
public static void main(String args[]) {
C obj = new C();
[Link]();
[Link](); }}
Implementación de la Interface
➢ Se debe definir una clase que implemente todos los
métodos de la interfaz.
➢ Una clase puede implementar una o más interfaces.
➢ Se utiliza para denotar esto con la palabra
implements.
➢ En caso de haber extends la palabra implements va
después de la super clase.
Implements
public class Pila implements Coleccion{
Void añadir(Object obj) { ….}
void borrar(Object obj) { ….}
Object buscar(Object obj) {…….}
int contadorActual() {….}
}
Inicialización de Interfaces
public interface Tabla { void dibujar(); }
public class TablaA implements Tabla {…. }
public class TablaB extends TablaA {… }
TablaA t=new TablaA(); ☺
TablaA t1=new TablaB(); ☺
TablaA t2=new Tabla();
La interfaz NO puede ser instanciada (aún cuando
una clase la implemente).
Clase Abstracta / Interface
Diferencias entre clases abstractas e interfaces:
➢ Clases abstractas:
• Pueden contener métodos concretos.
• Admiten atributos y constructores.
• Se utilizan cuando las clases tienen una relación jerárquica.
➢ Interfaces:
• Sólo contienen métodos abstractos.
• No pueden tener atributos excepto constantes.
• Se usan para definir un contrato sin imponer relaciones
jerárquicas.
Clase Abstracta / Interface
¿Cual conviene usar?
Las clases abstractas pueden proporcionar abstracción parcial o total. Las
interfaces, en cambio, siempre ofrecen abstracción completa.
Se puede crear una clase padre abstracta para algunas clases que
comparten funcionalidades. Las interfaces son preferibles cuando se desea
definir una estructura básica. El programador puede entonces construir
cualquier cosa con esta estructura.
Las interfaces también admiten herencias múltiples. Por lo tanto, una sola
clase puede implementar múltiples interfaces.
En general, es cuestión de elección y de la tarea a realizar. Tanto las clases
abstractas como las interfaces son adecuadas para diferentes propósitos y
deben utilizarse según corresponda.
Ejemplo instanceof
TablaA tgeneral [] = new TablaA [3];
tgeneral[0]= new TablaA();
tgeneral[1]= new TablaB();
tgeneral[2]= new TablaB();
Boolean max=false;
for(int i=0; i<3; i++){
if (tgeneral[i] instanceof TablaB) { max=true; }
If (max) [Link](¨Se ha almacenado al menos
un objeto de TablaB¨) ; }