viernes, 20 de junio de 2014

MODULO 6: Diseño de Clases

Herencia


protected -> clase + paquete + herencia (Aun cuando se herede dentro de otro paquete). Es una excepción ya que también funciona en otro paquete siempre y cuando herede.


LOS CONSTRUCTORES NO SON HEREDADOS


sobreescritura de metodos (overriding)

En el caso de los tipos de datos primitivos debe sobreescribir en la herencia exactamente el mismo tipo de retorno


En las clases de usuario si es posible regresar otro tipo de datos y estos deben ser
 - El mismo que la super clase
- Otras subclase.

Pero nunca un padre.
ninguna otra que  no herede.


Modificador de accesos

La sobrescritura
Una vez heredados los métodos sólo pueden ponerse los métodos de acceso, el que tiene el método o otro de abajo.

Si en clase padre tenemos un método de tipo Package los de abajo son protected y public, nunca uno modificador más arriba, en el caso de los private no aplica ya que no podemos heredarlos.


Polimorfimos
Es la habilidad de tener diferentes formas.

> El objeto sólo toma una forma
>


        Animal a = new Animal();
               a = new Aguila();
               a = new Perro();

a siempre va ha ser un Animal pero se comporta como Aguila y coo Perro.
El valor de 'a' se queda con el último, es decir se comportaría como un Perro.

Reglas del polimorfismo
**Una variable de referencia solo puede hacer referencia a objetos de su mismo tipo o subtipos.
**Un padre puede apuntar a un Padre o a un Hijo pero nunca al revés.


Revisar

public class Perro extends Mamifero {

    public String raza;

}

public class TestAnimal {
 
    public static void main(String[] args) {
        Animal a = new Animal();
               a = new Aguila();
               a = new Perro();
               //a.raza;  Marca error
    }
 
}

 //a.raza;  Marca error 
Aun cuando 

Si en animal tenemos una propiedad (atributo)  cuando se hereda y tenemos dos atributos exactamente igual en las dos clases, cuando hacemos a.edad suponiendo que edad esta en ambas de tipo public e inicializadas traera siempre la de la clase padre aun cuando la instancia esta de Perro(); esto porque un objeto siempre es lo mismo un Animal sólo cambian los comportamientos.


Una animal se puede comportar como Gato, Perro, Aguila pero los atributos siempre tendran los atributos de Animal.

Lo anterior quiere decir con eso mismo si imprimiría los comportamientos (Métodos) de la instanancia que estas haciendo.


CASTING (castear)
Sirve para cambiar la REFERENCIA de un tipo de dato a otro tipo de dato

Dos tipos de Casteo
Implicito
Explicito

Es decir hacia arriba y hacia abajo.
Compilación
Existe:
        - Hacia arriba. >  Perro pm = (Perro) mamifero;
        - Hacia abajo  >  Mamifero m = (Mamifero) perro;
 *En compilación no existe el Cast entre clases que no tienen la misma jerarquía.

Ejecución
        - Solo existe casting hacia arriba
        - Si intentas hacer DOWN  Casting obtendrás un ClassCastException


El padre NO SE ADAPTA a un hijo y sale un ClassCastException
El Hijo SI SE ADAPTA a un padre.

Un Ejemplo de esto es el siguiente código
Ej. Cast hacia arriba
       Mamifero m = new Mamifero(); //1
       Perro pm = (Perro) m;               //2
       pm.comer();                              // 3

Un mamífero es el Padre de Perro y en la linea 2 intentamos que un Padre se comporte como un hijo, es decir, que obtenga todos y cada uno de los métodos que el hijo tiene.

 Ahora bien si compila porque como esta en herencia Perro tiene métodos por herencia que Mamifero tiene pero en tiempo de Ejecución hay un error porque algunos métodos que tiene Perro no los encuentra en Mamifero.


Sobre carga
Mismo métodos pero con diferentes argumentos.


En herencia
¿Mismos argumentos?
Si -> Sobrescritura
No ->Sobrecarga 

La sobrecarga existe en:
  - Métodos.
  - Constructores.


Constructores
SI no pones constructor JAVA proporciona uno vacío, Si pones uno JAVA recoje su constructor

El constructor vacío que proporciona java en realidad tiene el super(), que es una invocación a la clase padre.
> Importante para la certificación.

Es decir esta algo así
 public Tiburon(){
        super();
    }

super() -> llama al constructor
super -> sirve para acceder a los métodos y atributos de la clase padre (siempre y cuando el modificador se acceso sea adecuado)

this() -< permite hacer llamadas entre constructores hermanos.

 public Tiburon(){
       this(); //marca error porque manda llamar recursivamente así mismo porque el this llama a constructores //vacio en este caso
    }

 public Tiburon(){
       this("nombre");  //correcto llama a su contructor hermano
    }

 public Tiburon(String n){
   super("nombre"); //Llama al constructor de la clase padre
    }

NO SE PUEDE MANDAR LLAMAR A UN CONSTRUCTOR POR SU NOMBRE SOLAMENTE HAY NIVELES Y SE DEBE UTILIZAR super() o this(). Solo puede existir this() o super() a la vez.

super() -> llama a constructores superiores
this() -> llama a constructores hermanos (los de esa clase pero con diferentes argumentos)

TODOS LOS CONSTRUCTORES INDEPENDIENTEMENTE DE LOS ARGUMENTOS TIENEN EL super() por lo tanto a fuerza a ir al constructor padre hasta llegar a Object.

si tenemos

class Animal{

public Animal(){
System.out.println("Soy Padre ");
}

}

class Tiburon{

public Tiburon(){ //Aquí siempre hay un super();  //quedaría asó
       super();
       System.out.println("Soy Hijo");
    }

}

Si llamamos al contructor Tiburon() en la salida tendríamos.
Soy Padre Soy Hijo

Primero va a las superiores.


Clase Object
El constructor por Object no tiene super()
Tiene dos métodos interesantes
equals()
toString()

El operador equals() compara si es el mismo tipo de objeto el contenido

Cuando sobrescribes el método equals también tienes que hacerlo con el hashCode el cual determina en base a pesos si de verdad son iguales.

El hashCode se ejecuta automáticamente cuando el equals manda true.

Clases Wrapper
Por cada dato primitivo java proporciona uno de clase, las clases wrappers son clases finales, lo cual queire decir que no pueden tener hijos (no puede heredar).

T. Primitivo    Clase wrapper
long                    Long
float                   Float
Int                      Integer
boolean              Boolean
short                   Short
byte                    Byte
char                    Character
double                 Double

Los primitivos se inicializan con 0, 0.0, 0.0F o a fin, en el caso de clases de usuario (como las Wrappers) y se inicizan con 0.

Estas clases a partir de la versión 6 se llevan entre sí es decir si me piden un int puedo mandarle un Integer y funciona porque java hace la conversión necesaria.

Envolver/desemvolver
package EjCW;

public class EjW {
 
 
    public static void main(String[] args) {
        Integer a=0;
        int b=0;
     
        m(a);//Lo desembuelve y le pasa el valor.
        m2(b); //Lo envuelve y le pasa la referencias
    }
    public static void m(int a){//Recibe una copia del valor
     
    }
 
    public static void m2(Integer a){//Como es un objeto sólo recibe referencias
     
    }
 
}