Ir al contenido principal

this super

Ahora que sabes de Herencia y modificadores de acceso es momento de ver dos palabras reservadas bastante importantes this y super. this y super son palabras reservadas utiles en el contexto de la herencia para referirse a los componentes de  las clases que componen una estructura de herencia y esto es algo que debes recordar y de ser posible tatuartelo en la parte baja de la espalda para llevarlo siempre y es que this y super son útiles para acceder a los constructores de las clases en la herencia lo que es vital cuando las clases no tiene constructores por defecto.

Pero que quiere decir cada uno de estos modificadores.

this; se refiere a la clase en la que estoy por lo general se usa para evitar la ambigüedad (cuando dos variables se llaman igual) o para acceder a los constructores de la misma clase.


el primer caso sucede cuando tenemos algo así;

public class UnaClase{

private int variable;

//las dos variable se llaman igual, renuncio esta es una vida que no merece ser vivida
public void setVariable(int variable){
 variable++;
}
}

como puedes ver arriba la variable de clase y la de la función se llaman igual así que al hacer el ++ cual variable fue aumentada ????.
Por dominio la variable declarada en la función es a la que nos estamos refiriendo es decir que la que aumento fue la variable de la función y la variable de la clase esta intacta. Ahora como solventar este dilema variabilistico simple con la palabra reservada this.
this nos permite hacer cosas como estas

public void setVariable(int variable){
 variable++;//aumentar la variable de función
this.variable++;//aumentar la variable de clase
this.variable=variable;//el uso mas común asignar la variable de función a la variable de clase
this.variable=variable/this.variable; //operar entre la variable de función y de clase
}

El segundo uso es acceder desde un constructor a o otro constructor de la misma clase, imagina que tienes una clase con un constructor muy especifico pero que a la vez se desea permitir inicializar la misma clase con una serie de variables por defecto  

public class UnaClase{

private int variable;
private String variable2;

//constructor mucho muy especifico
public UnaClase(int variable,String variable2){
 this.variable=variable;
this.variable2=variable2;
}

//constructor mucho muy generico
public UnaClase(){
this.variable=1;
this.variable2="string val";

}
}

Si miras con atención veras que los constructores tiene adentro código algo repetido lo que esta en contra de un principio de programación llamado DRY (do not repeat yourself) que significa no escribir dos veces el mismo código... y ahora quien podrá defendernos... yo el modificador colo.. diré this.

this sin argumentos se puede referir al constructor de la clase si se le llama como si este fuese una función así:

this();//esto se refiere al constructor vació o por defecto de esta misma clase   

Importante esto solo se hace dentro de otro constructor no escribas this() o this("hola") por toda la clase o en cualquier método.

Importante el constructor debe existir 

mejor ver un ejemplo para entenderlo, primero uno que funcione


public class UnaClase{

private int variable;
private String variable2;

//constructor mucho muy especifico
public UnaClase(int variable,String variable2){
 this.variable=variable;
this.variable2=variable2;
}

//constructor mucho muy genérico
public UnaClase(){
this(1,"string val");//taran!!! listo llamo a un constructor desde otro enviandole valores por //defecto

}
}

Ahora lo que no  se debe hacer:

1. solo puedo llamar constructores que existan y esta confusión siempre esta relacionada con el constructor por defecto  así que ¿cuando existe y cuando no existe un constructor por defecto?

primero cuando existe: en estos dos casos

cuando no se escribe ningún constructor para la clase

public class UnaCalse{

private int variable;

public void metodo(){}


}

 esta clase no define constructor alguno entonces el compilador le pone uno por defecto algo así

public UnaClase(){}//no es gran cosa pero permite instanciar la clase


cuando se especifica para ejecutar alguna acción al crear la clase

public class UnaCalse{

private int variable;

public UnaCalse(){//especifico el constructor
 variable=1;//realizo cualquier operación por ejemplo inicializa una variable
}

public void metodo(){} 
}
Ahora cuando no existe: si se especifica algún otro constructor y no se especifica el constructor por defecto decimos que la clase no tiene constructor vació o por defecto
 
public class UnaCalse{

private int variable;

public UnaCalse(int variable){//especifico un constructor con argumentos
   this();//ERROR NADIE ESPECIFICO UN CONSTRUCTOR VACIÓ ESTO NO COMPILA
this.variable=variable;

}

public void metodo(){} 
}
si existe un constructor con argumentos y deseo también tener un constructor vació debo especificar el constructor sin argumentos así;

public class UnaCalse{

private int variable;


public UnaCalse(){//CONSTRUCTOR VACIÓ, INÚTIL PERO EXISTE

}

public UnaCalse(int variable){//especifico un constructor con argumentos
   this();//BIEN AHORA SI EXISTE
this.variable=variable;

}

public void metodo(){} 
}
2. no llamar constructores en ciclos cerrados por ejemplo


public class UnaCalse{

private int variable;


public UnaCalse(){//constructor vació
 this(1);
}

public UnaCalse(int variable){//especifico un constructor con argumentos
   this();
}

public void metodo(){} 
}

viendo este código que puede suceder al llamar cualquiera de los dos constructores......  pues algo así

UnaCalse() llama a UnaCalse(int variable) llama a UnaCalse() llama a UnaCalse(int variable) llama a
UnaCalse() llama a UnaCalse(int variable) llama a UnaCalse() llama a UnaCalse(int variable) llama a
UnaCalse() llama a UnaCalse(int variable) llama a UnaCalse() llama a UnaCalse(int variable) llama a
UnaCalse() llama a UnaCalse(int variable) llama a UnaCalse() llama a UnaCalse(int variable) llama a

si un ciclo infinito.

super; se refiere a las clases mas inmediatas en la herencia y se usa para acceder a variables, funciones y constructores en la clase padre.

El primer caso es acceder al constructor de la clase padre, llamar al constructor de la clase padre es lo que debe hacer toda clase al ser instanciada y así no se especifique siempre lo va a hacer. Pero hay un problema ¿que pasa cuando la clase padre no tiene un constructor por defecto? ejemplo:

public class UnaCalsePadre{

private int variable;

public UnaCalsePadre(int variable){//especifico un constructor con argumentos
  this variable=variable;
}

public void metodo(){} 
}

public class UnaCalseHijo extends UnaCalsePadre{

private int variable;

public UnaCalseHijo (int variable){//especifico un constructor con argumentos

//AQUI HAY UN ERROR QUE IMPIDE QUE ESTO COMPILE
//SI MIRAS LA CLASE PADRE NO TIENE CONSTRUCTOR VACIÓ
//Y AQUI ESTOY TRATANDO DE LLAMAR DE FORMA IMPLÍCITA
//UN CONSTRUCTOR VACIÓ QUE NO EXISTE
  this variable=variable;
}

public void metodo(){} 
}
En este caso es cuando super entra en acción. Super al igual que this permite invocar el constructor de una clase en este caso el constructor de la super clase arreglando el problema de la siguiente forma.


public class UnaCalseHijo extends UnaCalsePadre{

private int variable;

public UnaCalseHijo (int variable){//especifico un constructor con argumentos

super(variable);//ARREGLADO AQUÍ SUPER PERMITE LLAMAR A UN CONSTRUCTOR   //LEGITIMO
  this variable=variable;
}

public void metodo(){} 
} 
IMPORTANTE LOS LLAMADOS A LOS CONSTRUCTORES SUPER Y THIS SIEMPRE DEBEN SER LO PRIMERO EN HACERSE EN UN CONSTRUCTOR!!!!


public UnaCalseHijo (int variable){//especifico un constructor con argumentos

  super(variable);//BIEN
  this variable=variable;
}

public UnaCalseHijo (int variable){//especifico un constructor con argumentos
  this variable=variable;
  super(variable);//MAL!!!!
}








Segundo uso para super llamar las variables y métodos de una clase padre con el operador ".". El punto permite llamar los métodos y variables de instancia de la superclase ejemplo.


public class UnaCalseAbuelo{

public int variable;

public void metodo(){} 
public void metodo1(){} 
}
public class UnaCalsePadre{

public int variable;

public UnaCalsePadre(int variable){//especifico un constructor con argumentos
  this variable=variable;
}

public void metodo(){} 
}

public class UnaCalseHijo extends UnaCalsePadre{

public int variable;

public UnaCalseHijo (int variable){//especifico un constructor con argumentos
  super(varialbe)   this variable=variable;
}

public void metodo(){
//como no hay otra variable en el dominio de función me refiero a la variable de esta clase
variable=1;
//this se refiere a la variable de esta clase
this.variable=1;
// super se refiere a la herencia en esta caso a la variable en la clase UnaCalsePadre
super.variable=1;
//metodo se refiere al metodo en el que estoy en esta clase es igual a decir this.metodo();
metodo(); 
//aqui me refiero al metodo en la clase UnaCalsePadre
super.metodo();  
//aqui me refiero al metodo en esta misma clase
 metodo1();  
//aqui me regreso toda la herencia hasta encontrar el metodo1() en la clase UnaCalseAbuelo
super.metodo1();   
//la diferencia esta en que el metodo() fue sobre escrito en UnaCalsePadre pero metodo1() no
}  

public void metodo1(){} 
}

Aquí termina la primera parte de this y super, diría que es todo pero no si miras bien aquí solo tenemos variables y métodos públicos, pero ¿como funcionan las cosas cuando las variables y los métodos tienen otros accesos como private, protected y default?

eso se vera en this super 2  "la venganza de cal-el" (click aqui)



Comentarios

Entradas populares de este blog

Conectarse al LDAP (directorio activo) utilizando JAVA

Un LDAP es un sistema de autenticación estándar utilizado por muchas compañías para controlar el acceso a aplicaciones y recursos. Por lo general se espera que cualquier nueva aplicación haga uso del LDAP para realizar la autenticación y controlar los permisos en forma unificada, la seguridad es transversal a todos los procesos que realiza una organización. Una vez regado el cuento a lo que vinimos, como conectarse a un LDAP. Lo primero que debes saber es que no se requieren librerías adicionales, JAVA en su distribución estandar ya cuenta con todo lo que necesitas. primero tres siglas que tienes que tener en cuanta. CN  = Common Name OU  = Organizational Unit DC  = Domain Component Para conectarse primero necesitas es instanciar un Objeto de la clase LdapContext, este se encargara de manejar la conexión al LDAP y las peticiones que se hagan al mismo. por consiguiente necesitara que le entregues una serie de propiedades de conexión. Esto lo haras con un Map de la siguiente

Clases anónimas JAVA (Anonymous Classes)

Código fuente articulo: https://www.dropbox.com/s/pzw44ot0ji2metl/Lambda.zip?dl=0 Las Clases anónimas en JAVA son una solución rápida para implementar una clase que se va utilizar una vez y de forma inmediata. Por ejemplo el  EventHandler  para un botón se puede implementar en la misma asignación valiendonos de la interfaz  EventHandler  que ya esta definida. Pero mejor vamos con un ejemplo mas simple. De la definición anterior concluimos dos cosas la primera es que para crear una clase anónima es necesario haber definido una interfaz, una clase o una clase abstracta. La clase anónima lo que hará sera implementar la interfaz definida o sobre escribir los métodos definidos. Para ilustrar esto utilizaremos el ejemplo del JAVA Tutorial https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html . en este ejemplo tenemos que implementar clases que cumpliendo con la interfaz Saludo sean capaces de saludar en diferentes idiomas. El paso uno sera definir la int

Paralelismo en JAVA Executors (ExecutorService, Callables y Futures).

Código fuente articulo: https://www.dropbox.com/s/jci67120hmd0uce/Paralelismo.zip?dl=0 Para manejo de concurrencia Java desde la versión 5 presento el Concurrency API  este presento una mejora substancial en el manejo de hilos y procesos en paralelo, antes solo contabas con Thread y Runnable. lo que te obligaba a controlar la creación y el numero de hilos de ejecución, no te entregaba un resultado del procesamiento y no te dejaba controlar las Excepciones que lanzara un hilo...un hilo se lanzaba y amenos que le enviaras un un CallBack perdías todo contacto con el. Para solucionar este problema se crearon dos tipos de objetos Callables y Futures. estos dos te permiten encapsular una tarea asignándole un tipo de Objeto que sera el valor de retorno y hacer seguimiento a las tareas que ejecuto en paralelo pudiendo preguntar si ya termino, que resultado lanzo y que excepciones ocurrieron. Arranquemos con la implementación de Callable, Callable es una interfaz que te permite defini