12 junio, 2020

2. Modificador static, referencia this, sobrecarga de constructores e inicializadores estáticos


LOGRO

Al término de esta publicación, ustedes crean clases clasificadas en paquetes, crean objetos, emplean los modificadores de acceso: public y private así como el modificador static y la referencia this en Java. Finalmente, aplican el concepto de encapsulamiento.

TEMARIO

· Modificador static
· Referencia this
· Sobrecarga de constructores
· Inicializadores estáticos
· Ejercicios + Link

ACTIVIDADES PROPUESTAS

· Ustedes emplean el modificador static y la referencia this.
· Ustedes entienden el concepto de sobrecarga.
· Ustedes reconocen una librería empleando métodos estáticos
· Ustedes emplean inicializadores estáticos.

1. MODIFICADOR: STATIC

Una variable de instancia es una variable de la que se crea una copia independiente para cada objeto de la clase. En cambio, una variable de clase es una variable de la que se crea una sola copia para todos los objetos de la clase. Para que una variable sea variable de clase hay que preceder su declaración con el modificador static. Las variables de clase se crean en el momento en que la clase se carga a la memoria, lo que ocurre antes de crear cualquier objeto de la clase. Esto significa que las variables de clase pueden existir aún cuando no exista objeto de la clase. Se puede acceder a una variable de clase pública a través de una referencia a un objeto de la clase o mediante el nombre de la clase.

Ejemplo 1

Haga que la clase Alumno cuente la cantidad de objetos creados.

package semana3;
public class Alumno {
 // Variables miembro
 private String nombre;
 private int nota1, nota2;
 public static int cantidad = 0;

 // Constructor
 public Alumno(String nom, int n1, int n2) {
  nombre = nom;
  nota1 = n1;
  nota2 = n2;
  cantidad++;
 }

 // Métodos de acceso: get/set
 public String getNombre() {
  return nombre;
 }

 public int getNota1() {
  return nota1;
 }

 public int getNota2() {
  return nota2;
 }

 public void setNota1(int n) {
  nota1 = n;
 }

 public void setNota2(int n) {
  nota2 = n;
 }

 // Operaciones
 public double promedio() {
  return (nota1 + nota2) / 2.0;
 }
}
A la pulsación de un botón, cree tres objetos y visualice sus contenidos. Muestre, además, la cantidad de objetos.
void procesar() {
   Alumno a1 = new Alumno("Juan",13,15),
          a2 = new Alumno("Pedro",16,17),
          a3 = new Alumno("María",14,20);
   listado(a1);
   listado(a2);
   listado(a3);
   imprimir("# objetos creados : " + Alumno.cantidad);
}

Resultado:

nombre : Juan
nota 1 : 13
nota 2 : 15
promedio : 14.0

nombre : Pedro
nota 1 : 16
nota 2 : 17
promedio : 16.5

nombre : María
nota 1 : 14
nota 2 : 20
promedio : 17.0

# objetos creados : 3

2. REFERENCIA: THIS 

Dentro de un método de la clase, la referencia this contiene la dirección de memoria del objeto que invocó al método. La referencia this es un parámetro oculto añadido por el compilador. Una de sus aplicaciones más comunes es cuando el nombre de un parámetro coincide con el nombre de una variable miembro. En este caso, su objetivo es diferenciar la variable miembro del parámetro en sí. 

Ejemplo 2 

Haga que los parámetros del constructor y de los métodos set tengan el mismo nombre que las variables miembro. Adicionalmente, agregue un método que calcule el mayor promedio entre 2 objetos de tipo Alumno.
package semana3;

public class Alumno {
   // Variables miembro
   private String nombre;
   private int nota1, nota2;
   public static int cantidad = 0;

   // Constructor
   public Alumno(String nombre, int nota1, int nota2) {
      this.nombre = nombre;
      this.nota1 = nota1;
      this.nota2 = nota2;
      cantidad++;
   }

   // Métodos de acceso: get/set
   public String getNombre() {
      return nombre;
   }

   public int getNota1() {
      return nota1;
   }

   public int getNota2() {
      return nota2;
   }

   public void setNombre(String nombre) {
      this.nombre = nombre;
   }

   public void setNota1(int nota1) {
      this.nota1 = nota1;
   }

   public void setNota2(int nota2) {
      this.nota2 = nota2;
   }

   // Operaciones
   public double promedio() {
      return (nota1 + nota2) / 2.0;
   }

   public Alumno mayorPromedio(Alumno obj){
      /* this contiene la referencia del objeto que invocó al método */
      if(this.promedio()>obj.promedio())
         return this;
      else
         return obj;
   }
}

A la pulsación de un botón, cree dos objetos y visualice sus contenidos. Muestre, además, la cantidad de objetos y el nombre del alumno con mayor promedio.
void procesar() {
  Alumno a1 = new Alumno("Juan", 15, 14), a2 = new Alumno("Pedro", 12, 13);
  listado(a1);
  listado(a2);
  imprimir("# objetos creados : " + Alumno.cantidad);
  Alumno objMaxProm = a1.mayorPromedio(a2);
  imprimir("El alumno con mayor promedio es:" + objMaxProm.getNombre());
 }

 void listado(Alumno x) {
  imprimir("Objeto:" + x);
  imprimir("Nombre:" + x.getNombre());
  imprimir("Nota1:" + x.getNota1());
  imprimir("Nota2:" + x.getNota2());
  imprimir("Promedio:" + x.promedio());
  imprimir("");
 }

3. SOBRECARGA DE MÉTODOS 

La sobrecarga de métodos consiste en crear varios métodos con el mismo nombre. Para diferenciar un método de otro, se utiliza el número y tipo de parámetros que tiene el método y no su tipo de retorno. Los constructores también pueden ser sobrecargados. 

Ejemplo 3 

Haga que las variables miembro de la clase Alumno se inicialicen por defecto y, luego, considere tres constructores.
package semana3;

public class Alumno {
   // Variables miembro
   private String nombre = "ninguno";
   private int nota1 = 88, nota2 = 88;
   public static int cantidad = 0;

   // Constructores
   public Alumno(String nombre, int nota1, int nota2) {
      this.nombre = nombre;
      this.nota1 = nota1;
      this.nota2 = nota2;
      cantidad++;
   }

   public Alumno(String nombre) {
      this.nombre = nombre;
      cantidad++;
   }

   public Alumno() {
      /*
      * En este caso el this se utiliza para llamar al segundo constructor
      */
      this("Monica");
   }

   // Métodos de acceso: get/set
   public String getNombre() {
      return nombre;
   }

   public int getNota1() {
      return nota1;
   }

   public int getNota2() {
      return nota2;
   }

   public void setNombre(String nombre) {
      this.nombre = nombre;
   }

   public void setNota1(int nota1) {
      this.nota1 = nota1;
   }

   public void setNota2(int nota2) {
      this.nota2 = nota2;
   }

   // Operaciones
   public double promedio() {
      return (nota1 + nota2) / 2.0;
   }
}

A la pulsación de un botón, cree tres objetos y visualice sus contenidos.
void procesar() {
   Alumno a1 = new Alumno("Juan",13,15),
          a2 = new Alumno("Pedro"),
          a3 = new Alumno();
   listado(a1);
   listado(a2);
   listado(a3);
   imprimir("# objetos creados : " + Alumno.cantidad);
}

Resultado:

nombre : Juan
nota 1 : 13
nota 2 : 15
promedio : 14.0

nombre : Pedro
nota 1 : 88
nota 2 : 88
promedio : 88.0

nombre : Monica
nota 1 : 88
nota 2 : 88
promedio : 88.0

# objetos creados : 3

4. MÉTODOS DE CLASE 

Así como existen variables de clase, existen métodos de clase. Para declarar un método como método de clase, hay que anteponer a su tipo de retorno la palabra static. Un método de clase puede operar únicamente sobre variables de clase y/o métodos de clase y no puede usar la referencia this. Se puede acceder a un método de clase público a través de una referencia a un objeto de la clase o mediante el nombre de la clase. 

Ejemplo 4 

Declare la clase Clase que cuente la cantidad de objetos creados. Luego, a la pulsación de un botón, cree tres objetos.
package semana3;

public class Clase {
   private static int contador = 0;

   public Clase() {
      contador++;
   }

   public static int getContador() {
      return contador;
   }
}

A la pulsación de un botón, cree tres objetos y visualice sus contenidos.
void procesar() {
   Clase c1 = new Clase(),
         c2 = new Clase(),
         c3 = new Clase();
   imprimir("# objetos creados :" + Clase.getContador());
}

5. APLICACIÓN DE MÉTODOS DE CLASE 

Una aplicación interesante donde empleamos métodos de clase es cuando creamos una librería, es decir, una clase que contenga métodos a los cuales invocaremos desde cualquier otra clase de un proyecto sin necesidad de crear un objeto. 

Ejemplo 5 

Diseñe una clase que contenga métodos que puedan ser invocados desde cualquier clase sin necesidad de crear un objeto.
package compartido;

public class LibNumeros {
   private LibNumeros() {
   }

   public static double pot(double num, double exp) {
      return Math.pow(num, exp);
   }

   public static double raizN(double num, double raiz) {
      return Math.pow(num, (1 / raiz));
   }

   public static double redondeoN(double num, int cant) {
      return Math.rint(num * pot(10, cant)) / pot(10, cant);
  }
}

El constructor de la clase tiene un acceso privado para que no pueda ser invocado y, de esta forma, no podrá crear un objeto de tipo LibNumeros. 

Descripción de los métodos de la clase LibNumeros: 

- Método pot: el método retorna la potencia de un número (parámetro num) elevado a un exponente (parámetro exp). 
- Método raizN: el método retorna la raíz (parámetro raíz) de un número (parámetro num). 
- Método redondeoN: el método retorna un número (parámetro num) redondeado a una cantidad de decimales indicada (parámetro cant). La llamada a los métodos sería de la siguiente manera:
void procesar(){
   imprimir("potencia de 5 elevado a 2:"+ LibNumeros.pot(5,2));
   imprimir("raiz cúbica de 27:"+ LibNumeros.raizN(27,3));
   imprimir("redondeo del número 13.44567 a 3 decimales:" +
   LibNumeros.redondeoN(13.44567,3));
}

Los resultados son: 

potencia de 5 elevado a 2: 25.0 
raiz cúbica de 27: 3.0 
redondeo del número 13.44567 a 3 decimales: 13.446

Ejemplo 6 

Otro ejemplo de librería, pero esta vez trabajando con cadenas:
package compartido;

public class LibCadenas {
   private LibCadenas() {
   }

   public static String mayus(String cad) {
      return cad.toUpperCase();
   }

   public static String minus(String cad) {
      return cad.toLowerCase();
   }

   public static String rellena(String cad, int num) {
      int tam = cad.length();
      for (int i = tam; i < num; i++)
         cad += ' ';
      return cad;
   }

   public static String extrae(String cad, int pos) {
      // pos en el rango de 1 .. longitud de la cadena.
      cad = cad.trim();
      int tam = cad.length();
      if (pos >= 1 && pos <= tam)
         return "" + cad.charAt(pos - 1);
      else
         return "Verifique los parámetros";
   }

   public static String extrae(String cad, int posIni, int posFin) {
      // pos en el rango de 1 .. longitud de la cadena.
     int tam = cad.length();
     if (posIni >= 1 && posFin <= tam)
        return cad.substring(posIni - 1, posFin);
     else
        return "Verifique los parámetros";
   }
}

Descripción de los métodos de la clase LibCadenas: 

- Método mayus: El método retorna la cadena en mayúsculas. 
- Método minus: El método retorna la cadena en minúsculas. 
- Método rellena: El método rellena con espacios una cadena (parámetro cad) de tal forma que la cadena este compuesta por la cantidad de caracteres especificados (parámetro num). 
- Método extrae: El método extrae es un método sobrecargado. Esto quiere decir que se puede invocar al método mandándole 2 parámetros (cadena y posición) o mandándole 3 parámetros (cadena, posición inicial y posición final). Si utilizamos la sintaxis: LibCadenas.extrae(cadena,pos); el método retornará una cadena que contenga el caracter que se encuentre en la posición pos. Si utilizamos la sintaxis: LibCadenas.extrae(cadena,posIni,posFin); el método retornará la cadena comprendida desde la posición inicial hasta la posición final indicada. 

La llamada a los métodos sería de la siguiente manera:
void procesar(){
   imprimir(LibCadenas.mayus("i7exe"));
   imprimir(LibCadenas.minus("I7EXE"));
   imprimir("|"+LibCadenas.rellena("hola",10)+"|");
   imprimir(LibCadenas.extrae("Cibertec",5));
   imprimir(LibCadenas.extrae("hola como estas",6,9));
}

Los resultados son:

I7EXE
i7exe
|hola |
r
como

6. INICIALIZADORES ESTÁTICOS 

Un inicializador static es un bloque de código definido en la clase que se llama automáticamente al cargarse la clase en la memoria. Se diferencia del constructor en que no es invocado para cada objeto, sino una sola vez para toda la clase. La forma de crear un inicializador static es la siguiente: 

static{
 . . . . . . 


Este bloque de código se utiliza para darle valores iniciales a las variables estáticas. También se utilizan para invocar a métodos nativos, es decir, métodos escritos por ejemplo en lenguaje C. En una clase, se pueden definir varios inicializadores estáticos, los cuales se ejecutan en el orden en el que han sido definidos.

Importante:

Cabe resaltar que, una vez que la clase se carga en la memoria (esto ocurre al crearse el primer objeto o al utilizar un variable o método static), primero se ejecutan los inicializadores static y, luego, el constructor de la clase.

Descargar ejercicios:
Descargar archivo

Preguntas:
¿Qué es una variables de instancia?
¿Qué una variable de clase?
¿Qué es el modificador static?
¿Que es la referencia this?
¿Qué es la sobrecarga de métodos?
¿Qué es la sobrecarga de constructores?
¿Qué es un método de clase?
¿En que momento emplear métodos de clase?
¿Qué son los inicializadores estáticos?

No hay comentarios, ¡cuéntame algo!

Me gustaría saber tu opinión. ¡Saludos!