static
.Las Clases van a servir para fabricar objetos de su tipo. Con ellas vamos poder encapsular el estado actual (atributos) y el comportamiento (métodos) de los objetos que vayamos creando (instanciando). Este encapsulamiento va a proteger a los miembros que lo necesiten de accesos no permitidos y va a ofrecernos la funcionalidad que corresponda con la responsabilidad de cada objeto. Así conseguimos tener valores agrupados que tienen relación entre ellos con una protección adecuada y un comportamiento que nos dará un valor añadido.
Con las Clases conseguimos tener valores agrupados que tienen relación entre ellos con un comportamiento y una protección adecuada que nos proporcionará un valor añadido
Si creamos una nueva clase con nombre
MiClase
y no marcamos la casilla para crear el método main, tendremos un archivo con este código: public class MiClase {
}
Vamos a ver que significan los modificadores:public
: Significa que vamos a tener visibilidad (acceso) a esta clase desde otras partes del código (desde otros ámbitos/scope). Esto es importante pues al no haber creado un métodomain
, no se ejecutará nada a menos que haya alguna llamada hasta esta clase desde un métodomain
. Si no tuviera este modificador sólo sería accesible desde su propiopackage
.class
: Define que es un tipo por referencia Clase. Recordad que hay más tipos por referencia, si pusierainterface
en vez declass
estaría declaran un tipo Interfaz.
MiClase
. Éste código aviso que va a ser un poco absurdo, pero es para ver conceptos. En la próxima sesión sobre Objetos ya usaremos un código de verdad funcional y con sentido. El código a usar es el siguiente: public class MiClase {
int miNumero;
private boolean miBoolean = true;
protected String string1 = "Primer";
public String string2; // mala practica
protected static String string3;
public int getMiNumero() {
return miNumero;
}
public boolean isMiBoolean() {
return miBoolean;
}
public String getString1() {
return string1;
}
private String getString2() { // absurdo
return string2;
}
void setString2(String string2) {
this.string2 = string2;
}
public static String getString3() {
return string3;
}
public static void setString3(String string3) {
MiClase.string3 = string3;
}
}
Vamos a detallar qué estamos definiendo en el código:- Atributos (Fields): Son declaraciones de variable al nivel raíz del cuerpo de la clase. Podemos hacer distinción entre variables de instancia y de clase:
- Variables de instancia: Atributos que tendrá cada objeto (instancia) que creemos de esta clase.
- Variable de clase: Son variables que no necesitan de ninguna instancia pues pertenecen a la clase en sí misma y es un valor único. Para declarar este tipo de variables se usa el modificador
static
(lo vemos en la declaración destring3
) - Hay nuevos modificadores que nos permiten proteger a los miembros estableciendo un control de acceso:
private
: Sólo se tiene acceso desde la propia clase.protected
: Sólo se tiene acceso desde los subtipos y su paquete (package
), además del accesoprivate
.public
: Igual que cuando la clase, vamos a tener acceso desde cualquier ámbito.(no modifier)
: Si nos fijamos en la declaración demiNumero
o desetString2
, vemos que no tienen ningún modificador. Si no se pone ninguno se entiende que es privado para el package (package-private
) además de la visibilidadprivate
. Todos estos modificadores pueden verse en la documentación de Java.- Hay variables que están inicializadas porque tienen asignado un valor como
miBoolean
ystring1
. Estos valores son valores por defecto y cada objeto se hará una copia de ellos. Así, los otrosString
s tendrán el valornull
que es el valor por defecto para los tipos por referencia, perostring1
tendrá el valor"Primer"
. - Hemos definido métodos al nivel raíz de la clase pero ahora sin el modificador
static
como siempre habíamos puesto hasta ahora (pues todos eran métodos de clase). Estos métodos son métodos de instancia (necesitan de un objeto) y se les conoce como miembros igual que a los atributos - Los métodos para acceder a los atributos comienzan por
get
. En general se llaman "getters" y por ahora sólo devuelven el valor que corresponde. - El getter de la variable
miBoolean
empieza por "is
" en vez de "get
". Para los métodos que devuelven booleanos ya dijimos que es habitual preguntares/estaAlgo()
en inglés como no hay diferencia se verá habitualmente "isSomething
" - Los métodos para asignar valores a las variables se llaman "setters", empiezan por
set
y reciben el valor para asignar. - En el método
setString2(String string2)
usamos la palabra reservadathis
. Es necesario usarla debido a que en el ámbito/scope de éste método el parámetrostring2
está ocultando el atributostring2
. Conthis
nos referimos al objeto en sí mismo y usando el punto (.
) accedemos a sus miembros, en este caso a su atributostring2
. De esta forma podemos asignar al atributostring2
el valor que le pasemos como argumento aunque el parámetro y el atributo tengan el mismo identificador. - Sin embargo a los miembros de clase (
static
) se accede desde el nombre de la clase en vez de usar el nombre de la variable como se puede ver en el métodosetString3
.
Existen publicaciones que consideran que los getters y setters (denominados más recientemente como accesors) son el mal y tratan a los objetos como meros recipientes de datos alejándonos de la POO. Desde mi punto de vista es pura semántica, simplemente cómo llamar a las cosas no te hará cambiar tu forma de pensar, y lo que recomiendo es que no se creen si no son necesarios y seguros. Ya iremos viendo como decidir esto último. También recomiendo siempre proteger las variables al máximo (en general
private
) y una vez creados los getters y setters usarlos siempre, incluso dentro de la propia clase (si quiero incorporar lógica en esas operaciones sólo debo cambiar el método que corresponda)
main
en otro archivo:
¿Si no hay "main
" cómo usamos MiClase
?
Evidentemente tendrá que haber un método main
que la llame desde fuera del archivo MiClase.java
. Vamos a crearnos otra clase llamada Ejecucion
con un main
y el siguiente código: public class Ejecucion {
public static void main(String[] args) {
MiClase miObjeto = new MiClase(); // creo una instancia
System.out.println("miNumero es " + miObjeto.miNumero);
// System.out.println("miBoolean es " + miObjeto.miBoolean); // sin acceso
System.out.println("miBoolean es " + miObjeto.isMiBoolean());
System.out.println("string1 es " + miObjeto.string1);
System.out.println("string1 tiene longitud " + miObjeto.string1.length());
// System.out.println("string2 es " + miObjeto.getString2(); // absurdo
System.out.println("string2 es " + miObjeto.string2);
MiClase.setString3("string-3");
// System.out.println("string3 es " + miObjeto.getString3()); // warning
System.out.println("string3 es " + MiClase.getString3());
}
}
Aquí vemos que hay miembros que podemos ver y otros que no. Esto es controlado por el acceso que demos al código con los modificadores antes explicados. Para acceder a los miembros uso la notación por punto (.), así si quiero acceder al atributo miNumero
del objeto referenciado por mi variable miObjeto
usaré miObjeto.miNumero
. Para los métodos es igual solo que añadiré a la invocación los paréntesis para cumplir con la firma que corresponda. En el vídeo hago unos cuantos cambios para verlo en profundidad.
Accedemos a los miembros de un objeto con el punto (
.
) limitados por el control de acceso que marquemos (public
, protected
, ...)
Aunque hemos construido un objeto del tipo
MiClase
todavía no hemos visto cómo personalizar su construcción. A falta de un constructor específico en MiClase
para crear objetos, Java siempre tiene un constructor por defecto que creará una instancia y asignará los valores por defecto que encuentre.En la siguiente sesión trabajamos con varios objetos y diferentes constructores.
No hay comentarios:
Publicar un comentario