Está en la página 1de 62

Polimorfismo

V6.0
Octubre 2016
Ferreiras

Ferreiras Polimorfismo en JAVA 1


Preámbulo

1. Sobrecarga de métodos en Java

2. Sobreescritura de métodos en Java

Ferreiras Polimorfismo en JAVA 2


Overloading o sobrecarga de
métodos en JAVA
Significa definir dos o más métodos dentro
de la misma clase, los cuales tienen el
mismo nombre, pero con diferentes
declaraciones de parámetros. Los tipos
de retornos podrán ser iguales o diferentes.
Lo único que se toma en cuenta son los
nombres de los métodos y sus listas de
parámetros.

Ferreiras Herencia en JAVA 3


 Cuando un método sobrecargado se
invoca, Java utiliza el tipo y / o número de
argumentos como guía para determinar qué
versión del método sobrecargado debe
llamar.

 Cuando Java encuentra una llamada a


un método sobrecargado, simplemente
ejecuta la versión del método cuyos
parámetros coincidan con los argumentos
utilizados en la llamada
Ferreiras Herencia en JAVA 4
 Por ejemplo:

overload0.java
jdk1.6.0_25

Ferreiras / JAVA / Sobrecarga de métodos (Overloading )

class Sobrecargada {
void fofi(String cad1) {
System.out.println( "\n\t=> " + cad1 );
}

void fofi(String cad, String cad2) {


System.out.println( "\n\t=> Concatenando: " + cad + " " + cad2 );
}

double fofi(double salarioAnual) {


System.out.println("\n\t=> Salario anual: " + salarioAnual );
return salarioAnual/12;
}
}

Ferreiras Herencia en JAVA 5


public class Overload0 {

public static void main(String args[ ]) {

Sobrecargada sobrecarga = new Sobrecargada();


double salarioMensual;
sobrecarga.fofi("El monigote de la ONU");
sobrecarga.fofi( "Ban-Kimoon" , " y de la OTAN" );
salarioMensual = sobrecarga.fofi(435237.12);
System.out.println( "\n\t=> Salario Mensual = " + salarioMensual );
}
}

Ferreiras Herencia en JAVA 6


/*

C:\Archivos de programa\Java\jdk1.6.0_25\bin>java Overload0

=> El monigote de la ONU

=> Concatenando: Ban-Kimoon y de la OTAN

=> Salario anual: 435237.12

=> Salario Mensual = 36269.76

C:\Archivos de programa\Java\jdk1.6.0_25\bin>

*/

Ferreiras Herencia en JAVA 7


 Cuando JAVA invoca un método
sobrecargado busca una coincidencia entre
los argumentos usados para llamar el
método y los parámetros del método. No
obstante, esta coincidencia no tiene
necesita ser 100 % exacta. Veamos en el
siguiente ejemplo Overload0b.java:

Ferreiras Herencia en JAVA 8


Obsérvese que se
public class Overload0b { esta invocando fofi
con un int; PERO, no
public static void main(String args[ ]) { se ha definido el
método fofi(int)
Sobrecargada sobrecarga = new Sobrecargada();
double salarioMensual;
sobrecarga.fofi("El monigote de la ONU");
sobrecarga.fofi( "Ban-Kimoon" , " y de la OTAN" );
salarioMensual = sobrecarga.fofi(435237.12);
int entero = 1234;
salarioMensual = sobrecarga. fofi(entero) ; // Invocara fofi( double ); <==
System.out.println( "\n\t=> Salario Mensual = " + salarioMensual );
}
}
Luego, JAVA hará la conversión a double
automáticamente por el mecanismo de promoción int
a double, y llamará a fofi(double)

Ferreiras Herencia en JAVA 9


C:\Program Files\Java\jdk1.6.0_22\bin>java Overload0b

=> El monigote de la ONU

=> Concatenando: Ban-Kimoon y de la OTAN

=> Salario anual: 435237.12

=> Salario anual: 1234.0 <== NOTESE LA CONVERSION A double

=> Salario Mensual = 102.83333333333333

C:\Program Files\Java\jdk1.6.0_22\bin>

 Ver el ejemplo Overload0b.java completo en el grupo.

Ferreiras Herencia en JAVA 10


 En el ejemplo anterior (Overload0b.java)
podemos ver que el código no definió un
método fofi(int) sino un método fofi(double).
En esta situación JAVA realizará la conversión
automática del tipo int a double y luego
llamará el método fofi(double).

Ferreiras Herencia en JAVA 11


 En resumen, los métodos sobrecargados:
 Tienen diferentes listas de parámetros;
 Los tipos de retorno pueden ser iguales o
diferentes. No importa;
 Pueden cambiar el modificador de acceso;
 Pueden declarar nuevas o más amplias
excepciones;
 Pueden estar en la misma clase o en una
clase derivada;

Ferreiras Herencia en JAVA 12


Overriding
[ sobreescritura de métodos ]
• Es una nueva definición, en una
clase derivada, de un método no
static ya definido en la clase base.
• El método sobrescrito tendrá en la clase
derivada el mismo modificador, el mismo
tipo de retorno, el mismo nombre y la
misma lista de parámetros, pero cuerpo
diferente.
Ferreiras Herencia en JAVA 13
• En situaciones en las que sea necesario
usar de manera explícita el método de la
clase base podemos usar la palabra
reservada “super” y para llamar de
manera expresa un método del objeto
actual podemos usar la palabra reservada
“this”.
• La nueva definición del método no
puede reducir la accesibilidad del
método original, pero si puede
ampliarla.
Ferreiras Herencia en JAVA 14
Herencia2.java
jdk1.6.0_25

Ferreiras / JAVA / Herencia / Overriding

class Animal {

public void mover() {


System.out.println("\n\t=> Un animal se mueve !!\n");
}
}

class Perro extends Animal {

public void mover() { // Override el metodo mover()


System.out.println("\n\t=> AVISO: Los perros pueden caminar, correr y morder\n");
}

Ferreiras Herencia en JAVA 15


public class Herencia2{

public static void main(String args[]){

Animal unAnimal = new Animal(); // referencia un objeto Animal


unAnimal.mover(); // Ejecuta el metodo mover en la clase base

Animal otroAnimal = new Perro(); // referencia un objeto Perro


otroAnimal.mover(); // Ejecuta el metodo mover() en la clase Perro

}
}

Ferreiras Herencia en JAVA 16


/*

C:\Archivos de programa\Java\jdk1.6.0_25\bin>java Herencia2

=> Un animal se mueve !!

=> AVISO: Los perros pueden caminar, correr y morder

C:\Archivos de programa\Java\jdk1.6.0_25\bin>

*/

Ferreiras Herencia en JAVA 17


/*
Herencia2a.java
jdk1.6.0_25

Ferreiras / JAVA / Herencia / Overriding / super

*/

class Animal {

public void mover() {


System.out.println("\n\t=> Un animal se mueve !!\n");
}
}

Ferreiras Herencia en JAVA 18


class Perro extends Animal {

public void mover() {


super.mover(); // invoca el metodo mover de la clase base
System.out.println("\n\t=> AVISO: Los perros pueden caminar, correr y morder\n");
}

public class Herencia2a {

public static void main(String args[]){

Animal unAnimal = new Perro(); // referencia un objeto Perro


unAnimal.mover(); // Ejecuta el metodo en la clase Perro

}
}

Ferreiras Herencia en JAVA 19


/*

C:\Archivos de programa\Java\jdk1.6.0_25\bin> java Herencia2a

=> Un animal se mueve !!

=> AVISO: Los perros pueden caminar, correr y morder

C:\Archivos de programa\Java\jdk1.6.0_25\bin>

*/

Ferreiras Herencia en JAVA 20


/*
Herencia2b.java
jdk1.6.0_25

Ferreiras / JAVA / Herencia / Overriding /

*/

class Animal {

public void mover() {


System.out.println("\n\t=> Un animal BASE se mueve !!\n");
}
}

Ferreiras Herencia en JAVA 21


class Perro extends Animal {

public void mover() {


super.mover(); // invoca el metodo mover de la clase base
System.out.println("\n\t=> AVISO: Los perros pueden caminar, correr y morder\n");
}

public void ladrar() {


System.out.println("\n\t=> URGENTE !! Estoy ladrando\n");
}

Ferreiras Herencia en JAVA 22


public class Herencia2b {

public static void main(String args[]){

Animal unAnimal = new Perro();


unAnimal.mover(); // Ejecuta el metodo en la clase Perro
// unAnimal.ladrar(); // VER NOTA # 1
Animal otroAnimal = new Perro(); // referencia un objeto Perro
otroAnimal.mover(); // Ejecuta el metodo mover() en la clase Perro

}
} NOTA # 1: Debido a que el método ladrar() NO ESTA EN LA
CLASE BASE REFERENCIADA con unAnimal, un error se
producirá en tiempo de compilación porque se esta invocando
un método de la clase Derivada con una referencia de la clase
Base.

Ferreiras Herencia en JAVA 23


D:\Ferreiras2\Java, Mi Codigo>javac Herencia2b.java

D:\Ferreiras2\Java, Mi Codigo>java Herencia2b

=> Un animal BASE se mueve !!

=> AVISO: Los perros pueden caminar, correr y morder

D:\Ferreiras2\Java, Mi Codigo>

Ferreiras Herencia en JAVA 24


/*

C:\Archivos de programa\Java\jdk1.6.0_25\bin>javac Herencia2b.java


Herencia2b.java:58: cannot find symbol
symbol : method ladrar()
location: class Animal
Error generado en tiempo
unAnimal.ladrar(); //
de compilación porque se
^
esta invocando un método
1 error
de la clase Derivada con
una referencia de la clase
C:\Archivos de programa\Java\jdk1.6.0_25\bin>
Base en la cual no está
dicho método , que solo
*/
esta en la derivada.

Ferreiras Herencia en JAVA 25


 En resumen, para sobreescribir los
métodos en la clase base:
 La lista de parámetros en el método sobreescrito debe ser exactamente la
misma que la lista del método en la clase base;

 El tipo de retorno en el método sobreescrito debe ser exactamente el


mismo tipo que el del método en la clase base o un subtipo de este.

 El nivel de acceso en el método sobreescrito no puede ser mas restrictivo


que el del método original en la clase base. Aunque si puede ser menor.

 Los métodos de instancia pueden ser sobreescritos solo si son heredados


por la clase derivada; Recordemos que los miembros private no son
heredados.

Ferreiras Herencia en JAVA 26


 Los métodos declarados “final” no pueden ser sobreescritos;

 Un método declarado static no puede ser sobreescrito pero puede ser


redeclarado;

 Si un método no puede ser heredado, este no puede ser sobreescrito;

 Una clase derivada en el mismo package de la clase base puede


sobreescribir cualquier método de clase base que no se declara “private” o
“final”;

 Una clase derivada en un package diferente al de la clase base puede


sobreescribir cualquier metodo de la clase base solo si no es “final” y es public
o protected;

 Un constructor no puede ser sobreescrito;

Ferreiras Herencia en JAVA 27


Fin del Preámbulo

Hablemos ahora de polimorfismo ...

Ferreiras Polimorfismo en JAVA 28


Polimorfismo
Es la capacidad de vincular una variable de
referencia a mas de un tipo de objeto. Puede
ser:
a) Polimorfismo estático: La vinculación se produce en tiempo de
compilación; Se implementa con la sobrecarga de métodos; O,

b) Polimorfismo dinámico: La vinculación se produce en tiempo de


ejecución. Se implementa con la sobreescritura de métodos.

El polimorfismo es el 3er. principio básico de la POO: “Una


interfaz, múltiples métodos”. Es uno de los pilares de la
TOO.

Ferreiras Polimorfismo en JAVA 29


Polimorfismo estático
• La sobrecarga de métodos es una de las
maneras que Java implementa el polimorfismo.
• Como hemos vista ya, en Java es posible definir
dos o más métodos de la misma clase que
comparten el mismo nombre, siempre y cuando
sus declaraciones de parámetros sean diferentes.
• Cuando este es el caso, los métodos se dice
que están sobrecargadas, y el proceso se conoce
como sobrecarga del método.

Ferreiras Polimorfismo en JAVA 30


Polimorfismo estático
• Los métodos sobrecargados deben
diferenciarse en el tipo y / o número de sus
parámetros y, aunque pueden tener
diferentes tipos de retorno, el tipo de
retorno por sí solo no es insuficiente para
distinguir dos versiones de un método.

Ferreiras Polimorfismo en JAVA 31


Polimorfismo estático
• Cuando Java encuentra una llamada a un
método sobrecargado, simplemente ejecuta la
versión del método cuyos parámetros coincidan
con los argumentos utilizados en la llamada.
• Cuando un método sobrecargado es invocado,
Java utiliza el tipo y / o número de argumentos
como guía para determinar qué versión del
método sobrecargado para llamar realidad.

Ferreiras Polimorfismo en JAVA 32


Polimorfismo estático
• Polimorfismo estático, viculación
temprana, sobrecarga de métodos
Son todos sinónimos.
• En los temas anteriores ya hemos
hecho uno que otro tipo de
polimorfismo.

Ferreiras Polimorfismo en JAVA 33


/*
Overload1.java
jdk 1.7.0_13

Ferreiras / Java/ Polimorfismo / Estático

Ejemplo del texto:

Java: the complete reference. By Herbert Schildt, Seventh Edition,


McGraw-Hill, 2007

Chapter 7: A Closer Look at Methods and Classes / Overloading


Methods, page 125

<< Ver link en la Referencia de esta PPT >>

*/

Ferreiras Polimorfismo en JAVA 34


class OverloadDemo {
void test() {
System.out.println("No parameters");
}
// Overload test for one integer parameter.
void test(int a) {
System.out.println("a: " + a);
}
// Overload test for two integer parameters.
void test(int a, int b) {
System.out.println("a and b: " + a + " " + b);
}
// overload test for a double parameter
double test(double a) {
System.out.println("double a: " + a);
return a*a;
}
}

Ferreiras Polimorfismo en JAVA 35


class Overload1 {
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo();
double result;
// call all versions of test()

ob.test();
ob.test(10);
ob.test(10, 20);
result = ob.test(123.2);
System.out.println("Result of ob.test(123.2): " + result);
}
}

Ferreiras Polimorfismo en JAVA 36


/*

This program generates the following output:

C:\Archivos de programa\Java\jdk1.7.0_11\bin>javac Overload1.java

C:\Archivos de programa\Java\jdk1.7.0_11\bin>java Overload1

No parameters
a: 10
a and b: 10 20
double a: 123.2
Result of ob.test(123.2): 15178.240000000002

C:\Archivos de programa\Java\jdk1.7.0_11\bin>

*/

Ferreiras Polimorfismo en JAVA 37


Polimorfismo dinámico
• El polimorfismo dinámico Significa que
cuando un método es llamado, la llamada
al método es vinculada al cuerpo del
método en el momento de ejecutar el
programa, dinámicamente.

Ferreiras Polimorfismo en JAVA 38


Polimorfismo dinámico
• En este caso, el compilador de JAVA no sabe qué
método es llamado en el momento de la
compilación.
• Sólo la JVM sabe en tiempo de ejecución qué
método seleccionar para ser ejecutado.
• Por lo tanto, esto también se llama "polimorfismo
en tiempo de ejecución" o "enlace dinámico“.
Otro nombre es “Vinculación tardía”

Ferreiras Polimorfismo en JAVA 39


Polimorfismo dinámico
• La vinculación tardía Hace posible que, con un método
declarado en una clase base (o en una interface) y
sobreescrito en las clases derivadas (o en clases que
implementan la interface), sea el tipo de objeto, y no el tipo
de la referencia lo que determine qué definición del método
se va a ejecutar.

• El tipo de objeto al que apunta una referencia solo puede


conocerse en tiempo de ejecución , y es por eso que el
polimorfismo dinámico necesita la vinculación tardía o
dinámica.

Ferreiras Polimorfismo en JAVA 40


• El polimorfismo dinámico esta asociado a una variable
polimórfica de referencia;
• Variable polimórfica  Es una variable que puede referenciar mas
de un tipo de objeto, en distintos momentos de la ejecución de un
programa ). Por ejemplo, si declaramos:

ClaseBase variableDeReferencia;

variableDeReferencia  Es,
entonces, una variable polimórfica
porque, en este caso, esta = new ClaseDerivada1
referenciando varios objetos de
las Derivadas de la Base.
= new ClaseDerivada2

variableDeReferencia 

= new ClaseDerivada

Ferreiras Polimorfismo en JAVA 41


 Por ejemplo:
Polimorfismo0.java
jdk1.6.0_22

Ferreiras / JAVA / Polimorfismo dinámico

class Animal {

public void hablar() {


System.out.println("\n\t=> Animal hablando\n");
}
}

class Mamifero extends Animal {

public void hablar(){


System.out.println("\n\t=> Mamifero hablando\n");
}
}

Ferreiras Polimorfismo en JAVA 42


class Caballo extends Mamifero {

public void hablar(){

System.out.println("\n\t=> Caballo hablando\n");


}
}

class Murcielago extends Mamifero {

public void hablar(){


System.out.println("\n\t=> Murcielago hablando\n");
}
}

Ferreiras Polimorfismo en JAVA 43


class Uso { ra es una Variable
referencia a la clase mas
Uso() { alta en la jerarquía

Animal ra;
Obsérvese que es el objeto
asignado a la variable
ra = new Animal();
referencia el que determina
ra.hablar();
qué método hablar()
seleccionar por la JVM para
ra = new Mamifero();
ejecutar
ra.hablar();

ra = new Caballo();
ra.hablar(); Luego, también vemos que
ra es una variable
ra = new Murcielago(); polimórfica, porque
ra.hablar(); referencia a diferentes
objetos durante la
} ejecución.

Ferreiras Polimorfismo en JAVA 44


// Probamos

public class Polimorfismo0 {


public static void main(String[ ] args) {
new Uso();
}

Ferreiras Polimorfismo en JAVA 45


C:\Program Files\Java\jdk1.6.0_22\bin> java Polimorfismo0

=> Animal hablando

=> Mamifero hablando

=> Caballo hablando

=> Murcielago hablando

C:\Program Files\Java\jdk1.6.0_22\bin>

Ferreiras Polimorfismo en JAVA 46


 La utilidad de los principios del
polimorfismo en JAVA tiene un buen
exponente en el uso de la clase JApplet
del paquete javax.swing, la cual tiene
varios métodos predefinidos de los que se
deben sobreescribir uno o mas para la
realización de un applet.

Ferreiras Polimorfismo en JAVA 47


Polimorfismo dinámico vía
las interfaces JAVA
En JAVA hay dos formas de implementar el
polimorfismo dinámico:
a) Vía la herencia ( Ya visto ); y,
b) Vía las interfaces de JAVA ( A ver ahora )
En los ejemplos de polimorfismo trabajados
hasta ahora siempre hemos usado la vía de
la herencia.
Ferreiras Polimorfismo en JAVA 48
• El polimorfismo dinámico vía las
interfaces de JAVA Se implementa
declarando variables de referencia con el
tipo de la interface.
• El nombre de una interface JAVA se
puede utilizar para declarar el tipo de una
variable, el valor de la variable puede ser
(de referencia) a un objeto de cualquier
clase que implemente esta interfaz.

Ferreiras Polimorfismo en JAVA 49


 Así, podremos utilizar los métodos de
la interface, vía la variable de referencia a
la que le fuese asignado un objeto de dicha
clase, sin mas que conocer el actual tipo de
objeto. Téngase en cuenta que la clase que
implemente la interface debe implementar
todos los métodos declarados en esta
ultima.

Ferreiras Polimorfismo en JAVA 50


 Por ejemplo:
/*
PolimorfismoInterface0.java
jdk1.6.0_22

Ferreiras / JAVA / Polimorfismo / Via interfaces JAVA /

Polimorfismo vía Interfaces JAVA

El nombre de una interface JAVA se puede utilizar para declarar el tipo de una
variable, el valor de la variable puede ser (de referencia) a un objeto de
cualquier clase que implemente esta interfaz. Así, podremos utilizar los
métodos de la interface, vía la variable de referencia a la que le fuese
asignado un objeto de dicha clase, sin mas que conocer el actual tipo de
objeto. Téngase en cuenta que la clase que implemente la interface debe
implementar todos los métodos declarados en esta ultima.
*/

Ferreiras Polimorfismo en JAVA 51


// Declaramos la interface JAVA

interface ProfesorEstudiante {

void elProfesor();
}

// Implementamos la interface

class Profesor implements ProfesorEstudiante { // Como ve el profesor al


// estudiante

public void elProfesor() {


System.out.println("\n\t=> El profesor es el Guru de esto !!\n");
}

Ferreiras Polimorfismo en JAVA 52


class Estudiante implements ProfesorEstudiante { // Como ve el estudiante al profesor

public void elProfesor() {


System.out.println("\n\t=> Todos tienen un 70 !!\n");
}

class Escuela implements ProfesorEstudiante { // Como ve la escuela el profesor

public void elProfesor() {


System.out.println("\n\t=> No debes faltar a clase !!\n");
}

public double evaluacionProfesor() { // metodo que esta en la interface


double evaluacion = 70;
return evaluacion;
}

Ferreiras Polimorfismo en JAVA 53


class usoClases {

usoClases() {
Obsérvese que usamos la
ProfesorEstudiante vr; misma variable de referencia del
tipo de la interface para ir
vr = new Profesor(); asignándole objetos de las
vr.elProfesor(); clases que la implementan y
poder invocar sus respectivos
vr = new Estudiante(); métodos. Eso también es
vr.elProfesor(); polimorfismo dinámico

vr = new Escuela();
vr.elProfesor();

// vr.evaluacionProfesor(); // ERROR

Ferreiras Polimorfismo en JAVA 54


// Probamos las clases

public class PolimorfismoInterface0 {

public static void main( String[ ] args ) {


usoClases uso = new usoClases();
}

Ferreiras Polimorfismo en JAVA 55


/*
La causa de este error es que
ERROR
intentamos usar la variable de
cannot find symbol referencia ,vr, con un método que
symbol : method evaluacionProfesor() no esta declarado en la interface
location: interface ProfesorEstudiante usada como tipo de la variable.
vr.evaluacionProfesor();
^

C:\Program Files\Java\jdk1.6.0_22\bin> java PolimorfismoInterface0

=> El profesor es el Guru de esto !!

=> Todos tienen un 70 !!

=> No debes faltar a clase !!

C:\Program Files\Java\jdk1.6.0_22\bin>

*/

Ver otro ejemplo en PolimorfismoInterface0b.java

Ferreiras Polimorfismo en JAVA 56


Polimorfismo, Herencia, Interface
• Los objetos de una clase Derivada de una clase Base
que implementa una interface pueden ser asignados a
las variables referencias que son del tipo de dicha
interface y, de esa manera, acceder a los métodos
declarados en tal interface.

• Ver código fuente en el ejemplo Polimorfismo4a.java,


cuya corrida se muestra en la siguiente diapositiva.

Ferreiras Polimorfismo en JAVA 57


Polimorfismo, Herencia, Interface
D:\Ferreiras2\Java, Mi Codigo>javac Polimorfismo4a.java

D:\Ferreiras2\Java, Mi Codigo>java Polimorfismo4a

*PROCESANDO UNA FACTURA

La Factura No. : 10023457


Total a pagar es : 2814.9959999999996

*PROCESANDO UN EMPLEADO

Entre las horas trabajadas en la semana: 10

El Emplado No. : 6665675


Tiene como nombre completo : Corpito Rico
El pago es: 501.1

D:\Ferreiras2\Java, Mi Codigo>

Ferreiras Polimorfismo en JAVA 58


EJEMPLOS

Ferreiras Polimorfismo en JAVA 59


EJERCICIOS

Ferreiras Polimorfismo en JAVA 60


GRACIAS.

Ferreiras Polimorfismo en JAVA 61


Referencias
• Java: the complete reference. By Herbert Schildt, Seventh Edition,
McGraw-Hill, 2007
Free PDF from
http://www.sahyadri.edu.in/SMCA/students_guide/3semnotes/java/Java
%20The%20Complete%20Reference,%207th%20Edition.pdf

Chapter 7: A Closer Look at Methods and Classes / Overloading Methods,


page 125

También podría gustarte