Mostrando entradas con la etiqueta computacion. Mostrar todas las entradas
Mostrando entradas con la etiqueta computacion. Mostrar todas las entradas

jueves, 11 de julio de 2013

Polimorfismo y Clases Abstractas


Polimorfismo y Clases Abstractas

Polimorfismo:

En programación orientada a objetos, se refiere a la posibilidad de acceder a un variado rango de funciones distintas a través del mismo interfaz. O sea, un mismo identificador puede tener distintas formas (distintos cuerpos de función, distintos comportamientos) dependiendo del contexto en el que se halle. 

Se puede establecer:

  • Sobrecarga
  • Sobre-escritura
  • Ligadura dinámica

Una misma llamada  ejecuta distintas sentencias dependiendo  de la clase ala que pertenezca el objeto al que se aplica el método.


Sobrecarga


El término sobrecarga se refiere al uso del mismo identificador u operador en distintos contextos y con distintos significados.


La sobrecarga de métodos conduce a que un mismo nombre pueda representar distintos métodos con distinto tipo y número de parámetros, manejados dentro de la misma clase. En el ámbito de la POO, la sobrecarga de métodos se refiere a la posibilidad de tener dos o más métodos con el mismo nombre pero funcionalidad diferente. Es decir, dos o más métodos con el mismo nombre realizan acciones diferentes. El compilados usará una u otra dependiendo de los parámetros usados. Esto también se aplica a los constructores. De hecho, es la aplicación más habitual de la sobrecarga.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Articulo {

    private float precio;

    public void setPrecio() {
        precio = 3.50;
    }
    public void setPrecio(float nuevoPrecio) {
        precio = nuevoPrecio;
    }
    public void setPrecio(float costo, int porcentajeGanancia) {
        precio = costo + (costo * porcentajeGanancia);
    }
}





Sobre-escritura:

La sobre-escritura, se aplica a los métodos y esta directamente relacionada a la herencia y se refiere a la re-definición de los métodos de la clase base en las subclases, por ejemplo, en la relación de herencia del ejemplo de las figuras aunque la clase base “Figura” tiene los métodos “calcularArea” y “calcularPerimetro”, las subclases “Circulo”, “Cuadrado”, “Triangulo” y “Rectangulo” redefinen estos métodos ya que el calculo del área y el perímetro de cada uno de ellos es diferente.


class Figura {
 protected double area;
     protected double perimetro;
     public Figura() {
       this.area=0;
         this.perimetro=0;
     }
     public double getArea() {
         return area;
     }
     public double getPerimetro() {
         return perimetro;
     }
     public void calcularArea(){}
     public void calcularPerimetro(){}
}

public class Circulo extends Figura {
     private double radio;
     public Circulo() {
         super();
     }
     public double getRadio() {
         return radio;
     }
    public void setRadio(double radio) {
         this.radio = radio;
     }
    public void calcularArea() {
       this.area = Math.PI*Math.pow(this.radio,2.0);
     } 
    public void calcularPerimetro() {
       this.perimetro = 2*Math.PI*this.radio;
 }
}



Enlace dinámico

Esto permite invocar operaciones en objetos obviando el tipo actual de éstos hasta el momento de ejecutar el código. O sea, nos permite definir elementos como un tipo e instanciarlos como un tipo heredado. Pero ¿qué utilidad tiene obviar el tipo de un objeto para luego tomar esta decisión?.
Gracias a que en java la definición de los tipos de objetos se puede producir por enlazado posterior (late binding), no nos debe preocupar a qué tipo de elemento le paso un mensaje, ya que el compilador tomará la decisión sobre qué objeto ejecutará qué método de acuerdo a la forma de crear la instancia.
Este concepto es bastante complejo de entender, ya que estamos acostumbrados a definir los elementos de acuerdo a lo que necesitamos. Es decir, si requiero un entero lo declaro como entero; ¿para que declarar un elemento como un tipo y luego usarlo como otro?. La respuesta está en que no siempre se puede determinar exactamente el tipo de elemento que va a usarse en la ejecución de nuestro programa.
Se debe tener por lo menos una relación de herencia que permita determinar un tipo base para la declaración, sea cual sea el subtipo que se instancie. Veamos un ejemplo que nos aclare un poco las cosas:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Mamifero {
  public void mover() {
    System.out.println("Ahora es un mamifero el que se mueve");
  }
}

class Perro extends Mamifero {
  public void mover() {
    System.out.println("Ahora es un perro el que se mueve");
  }
}

class Gato extends Mamifero {
  public void mover() {
    System.out.println("Ahora es un gato el que se mueve");
  }
}

public class Polimorfismo {
  public static void muevete(Mamifero m) {
    m.mover();
  }
  public static void main(String[] args) {
    Gato bisho = new Gato();
    Perro feo = new Perro();
    muevete(bisho);
    muevete(feo);
  }
}


CLASES ABSTRACTAS

       Una clase que declara la existencia de métodos pero no la implementación de dichos métodos, se considera una clase abstracta.

       Una clase abstracta puede contener métodos no abstractos pero al menos uno de los métodos debe ser abstracto.

       Para declarar una clase o método como abstractos, se utiliza la palabra reservada abstract. 


Una clase abstracta no se puede instanciar (es decir no se pueden volver en objetos) pero si se puede heredar y las clases hijas serán las encargadas de agregar la funcionalidad a los métodos abstractos

Declaración e implementación de métodos abstractos

Siguiendo con el ejemplo del apartado anterior, se puede escribir:
abstract class FiguraGeometrica {
    . . .
    abstract void dibujar();
    . . .
}

class Circulo extends FiguraGeometrica {
    . . .
    void dibujar() {
        // codigo para dibujar Circulo
        . . .
    }
La clase abstracta se declara simplemente con el modificador abstract en su declaración. Los métodos abstractos se declaran también con el mismo modificador, declarando el método pero sin implementarlo (sin el bloque de código encerrado entre {}). La clase derivada se declara e implementa de forma normal, como cualquier otra. Sin embargo si no declara e implementa los métodos abstractos de la clase base (en el ejemplo el método dibujar) el compilador genera un error indicando que no se han implementado todos los métodos abstractos y que, o bien, se implementan, o bien se declara la clase abstracta.

Referencias y objetos abstractos

Se pueden crear referencias a clases abstractas como cualquier otra. No hay ningún problema en poner:
FiguraGeometrica figura;
Sin embargo una clase abstracta no se puede instanciar, es decir, no se pueden crear objetos de una clase abstracta. El compilador producirá un error si se intenta:
FiguraGeometrica figura = new FiguraGeometrica();
Esto es coherente dado que una clase abstracta no tiene completa su implementación y encaja bien con la idea de que algo abstracto no puede materializarse.
Sin embargo utilizando el up-casting visto en el capítulo dedicado a la Herencia si se puede escribir:
FiguraGeometrica figura = new Circulo(. . .);
figura.dibujar();
La invocación al método dibujarse resolverá en tiempo de ejecución y la JVM llamará al método de la clase adecuada. En nuestro ejemplo se llamará al método dibujarde la clase Circulo.


Ejemplo de Polimorfismo


Public static void main(String[]args){
Personav[]=newPersona[10];
//Se introducen alumnos,profesores y personas en v
for(inti=0;i<10;i++)
/*Se piden datos al usuario de profesor,alumno o persona*/
switch(tipo){
case/*profesor*/:v[i]=newProfesor(….);break;
case/*alumno*/:v[i]=newAlumno(…);break;
case/*persona*/:v[i]=newPersona(…);break;
default:/*ERROR*/}
}
for(inti=0;i<10;i++)
System.out.println(v[i]);//enlace dinámico con toString()


Métodos abstractos

•Tenemos un método f()aplicable a todos los objetos de la clase A.
–Área de un polígono.

•La implementación del método es completamente diferente en cada subclase de A.
–Área de un triángulo.
–Área de un rectángulo.

•Para declarar un método como abstracto,se pone delante la palabra reservada abstract y no define un cuerpo:

Abstract tipo nombre Método (....);

•Luego en cada subclase se define un método con la misma cabecera y distinto cuerpo
Clases Abstractas

•Si una clase contiene almenos un método abstracto, entonces es una clase abstracta.

•Una clase abstracta es una clase de la que no se pueden crear objetos,pero puede ser utilizada como clase padre para otras clases.

•Declaración:

Abstract class Nombre Clase{

}



REPRESENTACIÓN DE JERARQUÍAS







APLICACIÓN DE  POLIMORFISMO 


Crearemos 3 clases con los respectivos nombres como la siguiente imagen





PARA LA CLASE MOTOR.JAVA




PARA LA CLASE MOTORFERRARI.JAVA



PARA LA CLASE MOTORBOCHO.JAVA




A CONTINUACIÓN EJECUTAMOS EL PROGRAMA Y OBTENDREMOS LO SIGUIENTE






APLICACIÓN  ABSTRACTA




DIGITAREMOS EN LA CLASE FUNCIONPRINCIPAL



LUEGO EN EL PACKAGE FUNCIONPRINCIPAL DIGITAMOS LO SIGUIENTE




EJECUTAMOS Y ECOJEMOS PERRO O GATO  (SI DIGITAMOS GATO)