jueves, 26 de junio de 2014

MODULO 7

  • Crear inicializadores, varibles y métodos estáticos.
La palabra static
Cuando se usa static, no pertenece al objeto si no a la clase

No pertenece al objeto, sino a la clase.
Puede ser compartida con todas las clases (la misma para todas).

Para acceder a un miembro static, se necesita el nombre de la clase+ punto + el miembro. Ej: clase.varStatic


Las variables static pueden ser accedidos desde un objeto de clase o desde una clase.
Clase c = new Clase();
c.varStatic;


Ejemplo de una variable static



package marciano;

public class Marciano{ 

    public static int cuentaMarciano=5; 

}

package marciano;
public class Rambo{ 
    public void mataMarciano(){ 
        if(Marciano.cuentaMarciano>0){
        Marciano.cuentaMarciano-=1;
        System.out.println("Un marciano ha muerto por Rambo, quedan "+ Marciano.cuentaMarciano+" vivos"); 
        }else{
        System.out.println("Rambo: todos los marcianos han muerto :(");
        } 
    } 


package marciano;
public class Santo{ 
    public void mataMarciano(){ 
        if(Marciano.cuentaMarciano>0){
        Marciano.cuentaMarciano-=1; 
        System.out.println("Un marciano ha muerto en manos de Santo, aun viven "+Marciano.cuentaMarciano +" marcianos");
        }else{
        System.out.println("Santo: todos los marcianos han muerto :(");
        }             
    } 
}


package marciano;
public class App{
public static void main(String args[]){
            
            Rambo r = new Rambo();
            Santo s = new Santo();
            r.mataMarciano();
            s.mataMarciano();
            
            System.out.println("queda: "+Marciano.cuentaMarciano);
}
}

Si ejecutamos App mostrará: -----
Un marciano ha muerto por Rambo, quedan 4 vivos
Un marciano ha muerto en manos de Santo, aun viven 3 marcianos
queda: 3


En caso de no ser static cuando Rambo entre ha matar un marciano será diferente a cuando Santo mate uno, es decir serian una variable para cada uno, no compartida.


Métodos estáticos
Los métodos estáticos de un padre, si es sobrescrito en un hijo debe conservar el modificador.


Reglas de los Métodos static:
Una método de tipo static es un método de clase y se accede clase.metodoStatic(); o bien con un objeto de clase en algunos casos.

También un método static puede ser accedido cuando se importa el paquete en el que esta usando importando el contexto estatico Ej. import static ua.pa.A.mFinal; donde mFinal es un métod static.
    - No es correcto dejarlo así import static ua.pa.A; o así import static ua.pa.*; Pero si es correcto así  import            static ua.pa.A.*;

    - El orden es import static NUNCA es static import

Los métodos static al igual que los atributos static NO se son alcanzados por el super. 

Pueden sobrescribirse pero deben conservar el modificador static, si no marca error. Es decir no se sobrescribe como tal pero si lo usas debes a fuerza ponerle el modificador static y respetar la regla de los modificadores de igual o menor nivel de acceso.

Cuando se tiene un objeto de tipo A y A es la clase padre y tiene el metodo static cuando hacemos A a = new B();, lo anterior suponiendo que B hereda de A y B tiene el método cuando hagamos a.metodoStatic(); nos traerá el del padre y no el del hijo.


-------------------------------
Recodar que cuando se hereda un método el tipo de retorno es el mismo cuando son casos finales o primitivas
String, Interger o primitivas
Si son clases de usuario en el de abajo si pueden ser de otro tipo de retorno y sobrescribirlos.


inicializadores static

class A{
static{

}

}

El inicializador tiene la característica que se carga sin que se invoque a la clase, es decir se carga primero.

Desde un CONTEXTO ESTÁTICO no puedes acceder a cosas no ESTÁTICOS, es decir no se pueden inicializar variables que NO SEAN STATIC

  • Crear variables, métodos y clases final.
La palabra final
Una clase que es final no puede tener hijos, es decir no es heredable o extendida.
Los métodos si los marcar finales no se pueden sobrescribir. Garantiza que ese método ya no sea modificado.



final int a; 
Esta variable es definida como constante y esta inicializada con 0.

tipos de constantes
- Si no se inicializan al momento de declararla, se debe inicializar en el constructor o La inicializas cuando la declaras.

final int a = 5; //o en el contructor

- constante compartida, pero se inicializa al momento de declararla
static final int a  = 5;

*Pero también puede crear un inicializador static y ahí definirla, ¿Cómo?
static int a;
static{

a = 5;
}

Porque el inicializador tiene la característica que se carga sin que se invoque a la clase, es decir se carga primero.

recordar:
Desde un CONTEXTO ESTÁTICO no puedes acceder a cosas no ESTÁTICOS, es decir no se pueden inicializar variables que NO SEAN STATIC.



  • Crear y utilizar tipos enumerados.
un enumerado es un conjunto finito de valores.
NO ES UNA CLASE
NO ES UN INTERFAZ

Es un ENUM

El ENUM se puede crear dentro de una clase y para tener acceso cambia a si se declara por separado.

Los enum NO SE PUEDEN;
- Hacer comparaciones.
- Operaciones Aritméticas.

si sólo agregas los valores NO necesita ; a menos que agregues algo más en el enum 

----------

package EjE;





public enum Palo {
    PICAS, CORAZONES, DIAMANTES, TREBOL
    
}

----------

si agregas algo, entonces;


package EjE;





public enum Palo {
    PICAS, CORAZONES, DIAMANTES, TREBOL;
    
    private final String nombre = "Samuel";
    
}

Los enumerados pueden tener:
Atributos
Métodos 
Constructores

El constructor sólo va a servir para inicializar los valores de tu descripción así es que debiera ser private.

Ejemplo de Enums




package EjE;




public enum Palo {
    PICAS("Picas"), CORAZONES("Corazones"), DIAMANTES("Diamantes"), TREBOL("Trebol");
    
    private final String nombre;
    
    private Palo(String n){
        this.nombre = n;
    }
    
//    como nuestra varibale es una constante que de asigna un valor en el constructor
//    debenos crear el siguiente método.
    public String getNombre(){
        return nombre;
    }
  
    
}


package EjE;

public class NaipeBaraja {

  private Palo palo;
 private int rango;
    
  

  public NaipeBaraja(Palo palo, int rango) {
    this.palo = palo;
    this.rango = rango;
  }
  
  public Palo getPalo(){
      return palo;
  }
  
  public int getRango(){
  return rango;
  }
  
}


package EjE;

public class TestNaipeBaraja {
  public static void main(String[] args) {

    NaipeBaraja naipe1 = new NaipeBaraja(Palo.CORAZONES, 2);
    System.out.println("el naipe1 es: " + naipe1.getRango() + " de " + naipe1.getPalo().getNombre());

    //Puede crear un naipe de un palo inventado.
    NaipeBaraja naipe2 = new NaipeBaraja(Palo.DIAMANTES, 2);
    System.out.println("el naipe1 es: " + naipe2.getRango()+ " de " + naipe2.getPalo());
                                                                                            //de manera bruta ^
  }
}



El resultado será: ---------------------
el naipe1 es: 2 de Corazones
el naipe1 es: 2 de DIAMANTES


Si el enum esta en otro lado, entonces la forma de acceso es:
nombre de la clase + punto + nombre del enumerado + punto + valor


  • Utilizar la sentecia import static.
import static EjE.Palo.*; //sirve para no tener que escribir de donde lo ponemos es decir para no pones Palo.CORAZONES Y solo 
//poner CORAZONES

No es necesario abusar.



  • Crear métodos y clases abstractas.
¿cómo hace un animal? no se sabe sabemos como hace un Perro o un Tigre pero un Anima (¿Qué animal?) para eso nos sirve las clases abstractas para definir que hace pero no cómo.

Las clases abstractas no se pueden instanciar pero sirve con:
Herencia
Polimorfismo

Es valido:
public abstract class A{}
abstract public class A{}

Método
public abstract void comer(); 

Si hay al menos un método abstracto entonces la clase debe ser definida como abstract.

Si heredas de un una clase abstract, entonces debes implementar los métodos abstractos y darle cuerpo.

Pueden tener métodos abstractos o no Abstractos.

Para utilizar un método no abstracto en una clase abstracta debes de instanciar un hijo y ya puedes acceder a el.


UNA CLASE HEREDA DE OTRA CLASE, NO IMPLEMENTA OTRA CLASE.
UNA CLASE IMPLEMENTA INTERFACES

****
SI UNA CLASE ES ABSTRACTA Y HEREDA DE OTRA CLASE ABSTRACTA NO ES NECESARIO QUE IMPLEMENTE LOS MÉTODOS DE LA CLASE PADRE.

Es decir si heredas de una clase abstract
O implementas sus métodos abstrac O haces la clase hija en abstrac


Los atributos no se declaran abstrac.



  • Crear y utilizar un interface.
Una interfaz es un contrato ( obligación ) que debemos de cumplir, si implementas una interfaz tienes que darle cuerpo a todos y cada uno de los métodos, aunque ese cuerpo solo tenga {  /* un comentario */ }, pero con que tenga las llaves eso significa que ya tiene cuerpo.

Indican que hacer. Y cada clase que implementa decide cómo lo vamos a utilizar.

se definen public interface nombre{}

Todos lo métodos por definición son publicos y abstractos (de una interfaz) aun cuando no le pongas public.

Las variables también se pueden inicializar en el inicializador y en en un contructor.

Una interfaz puede HEREDAR de UNA o MÁS interfaces. MÁS NO IMPLEMENTAR.

UNA INTERFAZ NO implementar DE NADA


Una clase puede heredar de una clase e Implementar de una o más interfaces.

//todos los métodos por definición son abstractos por lo tanto no llevan cuerpo 


Si una clase la marcas como abstracta no es necesario que le des cuerpo a todos los métodos de las interfaces o clases abstractas.

Todos los métodos sobrescritos de una interfaz son publicos por definición y sólo public.

lleve o no lleve el public abstract los métodos de una interfaz son public abstrac.

aun cuando tenga la combinación
public abstract void  m();
abstract void  m();
public void  m();

Todas son public abstract


Los modificadores de una variable en una itnerfaz sólo pueden ser
public
static
final 

cada uno por separado o los tres juntos.

Una clase abstract puede o no darle cuerpo a los métodos de la interfaz que hereda PERO como la clase que esta heredando no tiene por default el public abstract, hay que poner SÓLO el public porque si se pone abstract entonces no se le agregaría cuerpo.


se puede instanciar una interfaz siempre y cuando se implementen sus metodos



package ClasesInternas;


public interface Martillo {

    void golpear();
    
}

class TestMartillo{

    public static void main(String[] args) {
        Martillo a = new Martillo() {
            
            @Override
            public void golpear() {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        };  //ojo con el ;
        
    }

}



  • Crear clases internas
Sólo puede existir una clase pública en el MISMO ARCHIVO .java, pero si puede haber public dentro de otra clase, de decir dentro de una clase puede haber otra publica o private, pero no FUERA.

--inicia archivo .java ---
public class A{

 public class B{

  //       Aquí puede haber más metodos iguales a los de la clase A pero no marca error porque estan en //diferente clases aun cuando la clase B esta dentro de A.
Aquí no se permiten metodo main
    

}
}

class C{ // esta no puede ser public.

//es totalmente diferente que las demás y puede tener metodo main.

}


--termina archivo .java

Otro Ejemplo


package ClasesInternas;

public class Ex {
   
    private int a = 27;
    private void m(){
        System.out.println("Metodo Externo");
    }
   
   public  class Interna{
       int a = 424;
        private void m(){ //este método es diferente al de la clase Ex
            System.out.println("Soy otro metodo interno");
        }
     
    }
   
}

class Test{
    public static void main(String[] args) {
        Ex e = new Ex();
        Ex.Interna oInterno = e.new Interna();
     
        System.out.println(""+oInterno.a);
       
       M m = new M();
    }
   
}

class M{
   
}


Al compilar una clase que contiene otra aparece en clases NO estaticas
Ex.class //clase que tiene más
Ex$Interna.class //esta dentro de Ex

Si tenemos clases estáticas  la forma de INSTANCIAR es diferente


package ClasesInternas;

public class Ex {
   
    private int a = 27;
    private void m(){
        System.out.println("Metodo Externo");
    }
   
   public static class Interna{
       int a = 424;
        private void m(){ //este método es diferente al de la clase Ex
            System.out.println("Soy otro metodo interno");
        }
     
    }
   
}

class Test{
    public static void main(String[] args) {
        Ex e = new Ex();
        //Ex.Interna oInterno = e.new Interna();
       Ex.Interna oInterno = new Ex.Interna(); //OJO AQUI
        System.out.println(""+oInterno.a);
       
       M m = new M();
    }
   
}

class M{
   
}