jueves, 10 de mayo de 2018

HERENCIA Y POLIMORFISMO UNIDAD 4.



El concepto de herencia:



La herencia es específica de la programación orientada a objetos, donde una clase nueva se crea a partir de una clase existente. La herencia (a la que habitualmente se denomina subclase) proviene del hecho de que la subclase (la nueva clase creada) contiene las atributos y métodos de la clase primaria. La principal ventaja de la herencia es la capacidad para definir atributos y métodos nuevos para la subclase, que luego se aplican a los atributos y métodos heredados. 


Esta particularidad permite crear una estructura jerárquica de clases cada vez más especializada. La gran ventaja es que uno ya no debe comenzar desde cero cuando desea especializar una clase existente. Como resultado, se pueden adquirir bibliotecas de clases que ofrecen una base que puede especializarse a voluntad (la compañía que vende estas clases tiende a proteger las datos miembro usando la encapsulación). 

La principal ventaja de la herencia es la capacidad para definir atributos y métodos nuevos para la subclase, que luego se aplican a los atributos y métodos heredados. 

La herencia se define como el mecanismo mediante el cual se utiliza la definición de una clase llamada “padre”, para definir una nueva clase llamada “hija” que puede heredar sus atributos y operaciones.
A las clases “hijo” también se les conoce como subclases, y a las clases “padre” como superclases. La relación de herencia entre clases genera lo que se llama jerarquía de clases.

Jerarquía de clase 

La relación padre-hijo entre clases puede representarse desde un punto de vista jerárquico, denominado vista de clases en árbol. La vista en árbol comienza con una clase general llamada superclase (a la que algunas veces se hace referencia como clase primaria, clase padre, clase principal, o clase madre; existen muchas metáforas genealógicas). Las clases derivadas (clase secundaria o subclase) se vuelven cada vez más especializadas a medida que van descendiendo en el árbol. Por lo tanto, se suele hacer referencia a la relación que vincula una clase secundaria con una clase primaria mediante la frase es una x o y. 






Herencia múltiple (en java no es permitida este tipo de herencia ).

Algunos lenguajes orientados a objetos, como C++ permiten herencias múltiples, lo que significa que una clase puede heredar los atributos de otras dos superclases. Este método puede utilizarse para agrupar atributos y métodos desde varias clases dentro de una sola.




EJEMPLO:
Si una clase B hereda de otra clase A entonces:
„ B incorpora la estructura (atributos) y comportamiento (métodos) de la clase A
„ B puede incluir adaptaciones:
1.„ B puede añadir nuevos atributos
2.„ B puede añadir nuevos métodos
3.„ B puede redefinir métodos
 B puede redefinir atributos



Clases Abstractas:
Las clases abstractas no pueden ser instanciadas.
Sirven únicamente para declarar subclases que deben redefinir  aquellos métodos que han sido declarados abstract.
Esto no quiere decir que todos los métodos de una clase abstracta deban ser abstractos, incluso es posible que ninguno de ellos lo sea. Aún en este último caso, la clase será considerada como abstracta y no podrán declararse objetos de esta clase.
Cuando alguno de los métodos de una clase es declarado abstracto, la clase debe ser obligatoriamente abstracta, de lo contrario, el compilador genera un mensaje de error.
Definición: un método abstracto es un método de una clase (o también de una “interface” en Java) que no tiene implementación o definición (es decir, sólo tiene declaración). Sus principales usos son, en primer lugar, como un “parámetro indefinido” en expresiones que contienen objetos de dicha clase, que debe ser redefinido en alguna de las subclases que heredan de dicha clase (o que implementan la “interface”). En segundo lugar, sirve para definir “interfaces abstractas” de clases (entendido como partes públicas de las mismas) que deberán ser definidas por las subclases de las mismas.
Presentamos ahora un ejemplo sencillo de método abstracto que nos permita ilustrar mejor su utilidad. 

 Ejemplo
1
2
3
4
5
6
7
8
9
10
11
public abstract class Figura {
    // Atributos:
    public int numeroLados;
    public int area;
    public int volumen;
    // Métodos:
    abstract public void calcularArea();
    abstract public void calcularVolumen();
}



En este poco original ejemplo se puede apreciar que toda figura tiene un método para calcular su Área y Volumen.


Ahora creemos la clase Esfera, que “Es una” Figura.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Esfera extends Figura{
    public float radio;
    public static float pi = (float)(3.1415);
    public Esfera( int radio ){
        this.radio = radio;
        this.numeroLados = 0;
    }
    // 4*pi*r²
    public void calcularArea(){
        this.area =  (4)*pi*radio*radio;
    }
    // (4/3)*pi*radio³
    public void calcularVolumen(){
        this.volumen =  (4/3)*pi*radio*radio*radio;
    }
}



ATENCIÓN:

– Las clases que hereden de la clase Abstracta deben implementar todos los métodos abstractos.

– Se debe tener presente que las clases abstractas sí pueden heredar de otras clases.

– La firma o parámetros de los métodos así como el tipo de dato deben respetarse, de lo contrario se está hablando de otro método totalmente diferente.


Si una clase abstracta está compuesta sólo por métodos abstractos y constantes entonces podemos hablar de una interface.


Clases finales:



Se puede declarar una clase como final, cuando no nos interesa crear clases derivadas de dicha clase. La clase Cuadrado se puede declarar como final, ya que no se espera que ningún programador necesite crear clases derivadas de Cuadrado.

final class Cuadrado extends Rectangulo{  

public Cuadrado(int x, int y, double dimension)

 super(x, y, dimension, dimension);
 } 
}




Uno de los mecanismos que tienen los hackers para dañar o para obtener información privada en los sistemas es la de crear una clase derivada y sustituir dicha clase por la original. La clase derivada actúa exactamente igual que la original pero también puede hacer otras cosas, normalmente dañinas. Para prevenir los posibles daños, se declara la clase como final, impidiendo a cualquier programador la creación de clases derivadas de ésta. Por ejemplo, la clase String que es una de las más importantes en la programación en lenguaje Java, está declarada como final. El lenguaje Java garatiza que siempre que se utilice un string, es un objeto de la clase String que se encuentra en el paquete java.lang.String, y no cualquier otro string.




Una clase declarada final impide que pueda ser superclase de otras clases. Dicho de otra forma, ninguna clase puede heredar de una clase final.

Una clase no puede ser a la vez abstract y final ya que no tiene sentido, pero sí que puede ser public abstract o public final.

Métodos finales:

Como se ha comentado al introducir la herencia, una de las formas de aprovechar el código existente, es la de crear una clase derivada y redefinir algunos de los métodos de la clase base.
class Base{
//...
final public void funcionFinal(){
//...
}
public void dibujar(Graphics g){
}
}
class Derivada{
//...
//dibujar algunas figuras
public void dibujar(Graphics g){
}
}


La clase Base define una función miembro pública dibujar, que no dibuja nada en el contexto gráfico g. La clase Derivada redefine la función miembro dibujar, para dibujar algunas figuras en el contexto grafico g. La función que se redefine tiene que tener la misma declaración en la clase Base y en la clase Derivada. 


Para evitar que las clase derivadas redefinan una función miembro de una clase base, se le antepone la plabara clave final. La función miembro funcionFinal de la clase Base no se puede redefinir en la clase Derivada, pero si se puede redefinir la función miembro dibujar. 



Métodos Estaticos:


Los métodos static únicamente pueden acceder a sus atributos static y nunca a los atributos de objeto (no static).



—Los métodos static son métodos de clase (no de objeto) y por tanto, no necesita instanciarse la clase (crear un objeto de esa clase) para poder llamar a ese método.


Las variables y métodos estáticos en Java sirven para que puedan ser accedidos desde cualquier parte del código (inclusive desde otras clases) sin tener que crear un objeto. Un ejemplo muy común en donde se puede utilizar variables estáticas es cuando se necesita definir una configuración global en un proyecto.

Atributos estáticos:

Cuando los programas trabajan con múltiples objetos al mismo tiempo, puede suceder que éstos necesiten compartir información.



En este caso, puede utilizar la palabra clave static para indicar al compilador de Java que debe compartirse esa variable.


ejemplos:


Para realizar esta tarea vamos a crear la clase “Persona”, la cual va a tener dos variables estáticas(nombre y edad).
1
2
3
4
public class Persona {
    public static String nombre;
    public static int edad;
}
Luego para poder acceder y establecer nuevos valores a esas variables tenemos que hacer “Persona.nombreVariable” como se muestra a continuación:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Persona {
    public static String nombre;
    public static int edad;
    public static void main(String[] args) {
        Persona.nombre = "Juan";
        Persona.edad = 12;
        System.out.println("Nombre: "
Persona.nombre + "; Edad: "+ Persona.edad);
    }
}
Es importante aclarar que el ejemplo anterior no tiene mucho sentido y solamente sirve para explicar cómo definir variables.
Cómo definir y utilizar métodos estáticos en Java:
Crear métodos estáticos es muy parecido que hacerlo con variables, en este caso vamos a seguir con el ejemplo anterior para agregar el método estático “imprimirDatos” a la clase “Persona”:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Persona {
    public static String nombre;
    public static int edad;
     
    public static void imprimirDatos(){
        System.out.println("Nombre: " + Persona.nombre
 + ";edad: "+ Persona.edad);
    }
    public static void main(String[] args) {
        Persona.nombre = "Juan";
        Persona.edad = 12;
        Persona.imprimirDatos();
    }
}




Es muy importante entender que las variables y métodos estáticos solamente pertenecen a la clase donde están definidos y son globales, entonces si se quiere crear una clase “Persona” e instanciarla para distintas personas, esta clase no nos va a servir.


Bueno gente, espero que les sirva este sencillo tutorial en el cual se explica cómo crear variables y métodos estáticos en Java y ante cualquier problema no duden en enviar un mensaje.


Interfaces:

En Java no está permitida la herencia múltiple (más de una superclase).
  class  alumno extends persona, hijo, cuidadano{
Una aproximación a este concepto es la utilización de una sola superclase y una o varias interfaces.
class  alumno extends persona implements hijo, cuidadano{
Una interface es un conjunto de constantes y métodos abstractos.
Cuando una clase declara una lista de interfaces mediante la cláusula implements hereda todas las constantes definidas en el interface y se compromete a redefinir todos los métodos del interface ya que estos métodos son abstractos (no tienen implementación o cuerpo).
Mediante el uso de interfaces se consigue que distintas clases implementen métodos con el mismo nombre. De esta forma se comprometen a implementarlas.
Un interface se declara de forma similar a las clases.
Sintaxis:
  Declaración de interface {
  Cuerpo de interface
  }
En la declaración de una interface:
[ public] interface NombreInterface [ extends ListadeSuperInterfaces] 
A diferencia de las clases, que únicamente pueden heredar de una superclase, las interfaces pueden heredar de varias interfaces mediante la cláusula extends.
La lista de superinterfaces de las que hereda se enumera mediante los nombres de las mismas separados por comas y precedidos por la palabra reservada extends.
  Por ejemplo:
public  interface  Operable extends OperableAritmético, OperableLógico {
En este caso, la interface Operable heredaría todas las constantes y métodos de las interfaces OperableAritmético y OperableLógico, pudiendo redefinirse en la interface Operable si fuera necesario.
En el Cuerpo de la interface:
Se declaran los métodos y las constantes del interface.
Todos los métodos declarados en el cuerpo del interface son públicos  y abstractos (public y abstract) sin que sea necesario declararlos de este modo explícitamente.
Todos los atributos declarados en el cuerpo del interface, si existen, son constantes.
  public interface OperableAritmetico {
  double PI=3.14;
  double suma();
  double resta();
  }

Las interfaces, tal como las clases abstractas. no se pueden instanciar. Sus métodos deben ser re-escritos por la clase que implemente.
Ejemplo fome:
1
2
3
4
5
6
7
8
9
10
public interface MatematicaVectorial {
 public static double pi    = 3.1415;
 public static double e     = 2.71828;
 public double[] sumar(int[][] vectores);
 public double[] restar(int[][] vectores);
 public double productoPunto(int[][] vectores);
}
La clase VectorR3, que es un vector de R³ implementa MatematicaVectorial


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class VectorR3 implements MatematicaVectorial
{
    public double valorX;
    public double valorY;
    public double valorZ;
    public double[] sumar(int[][] vectores){
        //Implementacion
    }
    public double[] restar(int[][] vectores){
        //Implementacion
    }  
    public double productoPunto(int[][] vectores)
    {
        //Implementacion
    }
}
Polimorfismo:
Polimorfismo es un término que se utiliza para describir una situación en donde un nombre puede referirse a diferentes métodos. En java existen dos tipos de polimorfismo:
El que ocurre en la sobrecarga y
El que ocurre en el reemplazo
El polimorfismo en la sobrecarga sucede cuando existen varios métodos dentro de una clase, todos ellos con el mismo nombre, lo cuál está permitido siempre y cuando los métodos tenga diferente número o tipos de parámetros.

Polimorfismo en la sobrecarga:

El polimorfismo de sobrecarga ocurre cuando las funciones del mismo nombre existen, con función similar, en clases que son completamente independientes unas de otras (estas no tienen que ser clases secundarias de la clase objeto). Por ejemplo, la clase complex, la clase image y la clase linkpueden todas tener la función display. Esto significa que no necesitamos preocuparnos sobre el tipo de objeto con el que estamos trabajando si todo lo que deseamos es verlo en la pantalla. 


Por lo tanto, el polimorfismo de sobrecarga nos permite definir operadores cuyos comportamientos varían de acuerdo a los parámetros que se les aplican. Así es posible, por ejemplo, agregar el operador + y hacer que se comporte de manera distinta cuando está haciendo referencia a una operación entre dos números enteros (suma) o bien cuando se encuentra entre dos cadenas de caracteres (concatenación).

class Persona{
  void trabaja() { }
  void trabaja(int hrs) { }
  void trabaja (String lugar, int hrs) { }
}
Persona juan = new Persona();
juan.trabaja();
juan.trabaja(5);
juan.trabaja(“Escuela”,8);

Polimorfismo en el reemplazo:
Para que Java determine qué métodos debe llamar, debe considerar no sólo los que están dentro de una clase, sino a los que están en las superclases (clase padre).
El reemplazo ocurre cuando un método en una clase tiene el mismo nombre y firma (número, tipo y orden de los parámetros) que un método de una clase padre.
En el caso de que los métodos de la clase padre e hija tengan la misma firma, el método de la clase derivada siempre reemplaza al método de la clase padre.
  void operar(){
  System.out.println("Genérica");
  }
}
class Desarmador extends Herramienta{
  void operar(){
  System.out.println("Desarmador");
  } 
}
public class Hazlo{
  public static void main(String[] args){
  Herramienta generica = new Herramienta();
  Desarmador phillips = new Desarmador();
 
  generica.operar();
  phillips.operar();
 
  generica=phillips;
  generica.operar();
  }
}

No hay comentarios:

Publicar un comentario

comentarios...