Java, un lenguaje de Bloques no de Objetos...

Hola chavos, para empezar este año quiero tocar un tema que en lo personal cuando estaba aprendiendo Java me llamo mucho la atención. Cabe mencionar que mi objetivo en este post no es el de reinventar la rueda o cosas por el estilo, es solo algo que me llamo mucho la atención y tras meditarlo mucho llegue a una conclusión.

Durante la universidad, preparatoria o por cualquier medio que hayamos aprendido Java se nos dice que Java es un lenguaje orientado a objetos, pero que significa la frase: orientado a objetos? POO o OOP (por sus siglas en ingles: Object Oriented Programming) es un paradigma el cual nos dice que todo es un Objeto, los cuales contienen atributos y comportamientos que interactuan entre si. Para saber un poco mas acerca de lo que es POO, pueden darse una vuelta por wikipedia, ya que este tema es algo extenso y no es el propósito de este post.

//Entremos en Materia...

Bueno, regresando al tema, todos ubicamos que son los bloques, no? bueno para los que no saben o no lo recuerden los bloques en Java son todas aquéllas lineas de código que estén rodeadas por llaves, ej:

//Ejemplo de bloques

{
 System.out.println("Esto es un bloque");
}

En Java existen 3 tipos de bloques, los mas usados por todos son los bloques de sentencia(if, for, while, do),  ej:

//Ejemplo de bloques de sentencia
if(true){
 System.out.println("Bloque de sentencia IF");
}

 Para ver mas ejemplos de bloques de sentencia, pueden visitar mi Ideone. Bien ahora que ya entendemos lo que son los bloques, que es en realidad un Objeto en Java? Bueno un Objeto, no solo en Java, si no en programacion es todo aquello que tiene al menos un atributo y un comportamiento, pongamos un ejemplo: Un perro! Los perros tienen varios atributos: nombre, raza, color, etc. a la vez que también tienen varios comportamientos: hambriento, cansado, jugando, etc. Bueno en Java los atributos son variables y los comportamientos son métodos o funciones. Para crear cualquier objeto en Java, necesitamos instanciar* nuestro contructor, veamos el ejemplo de una clase simple (para verlo funcionar, vayan a mi Ideone):

class Perro{
 //Los perros tienen atributos:
 String nombre, raza;
 int edad;

 //Y tienen comportamiento:
 public void ladra(){
  System.out.println("Wow wow!");
 }

 //Siempre que se creen los perros, necesitamos asignarle su nombre y su edad
 Perro(String nombre, int edad){
  this.nombre=nombre;
  this.edad=edad;
 }

 public static void main(String args[]){
  Perro firulais = new Perro("firulais",23);
  firulais.ladra();
 }
}

* Instanciar es el proceso de crear un nuevo Objeto en memoria. Para esto necesita de la palabra clave: new, como podemos ver en el ejemplo anterior, la Instancia o el Objeto de Perro se guarda en una variable de tipo Perro llamada firulais en la linea: Perro firulais = new Perro();

Bien, ahora ya entendemos lo que son bloques y Objetos, porque es esto importante? simple si ya se dieron cuenta, la clase en si es un bloque! al igual que su contructor:

//CLASE
class Perro{
 //Codigo extra...

 //BLOQUE DE INSTANCIA
 Perro(String nombre, int edad){
  //Codigo extra...
 }

 //BLOQUE ESTATICO
 public static void main(String args[]){
  //Codigo extra...
 }
}

//Estatico, Instancia o Inmutable?

Que es estático? A que me refiero con "instancia"? Estático es lo mismo que inmutable? Existe una diferencia entre lo estático y lo de instancia?... Quisas en este mismo momento se están preguntando lo mismo o incluso mas cosas; empecemos por partes, en Java tenemos muchas palabras reservadas, bueno dentro de esas palabras reservadas tenemos las palabras: static, new y final. Cual es la diferencia entre estas? Veamos la respuesta a continuación se muestra:

  • static:
    • Es la palabra reservada usada para definir variables o métodos estáticos
    • Un elemento estático en Java no es lo mismo que una variable constante, el elemento estático son aquellos que son miembros de la clase
  • new:
    • Usada para instanciar/crear un Objeto
    • Cuando se instancia un Objeto, las variables de instancia son inicialisadas, las variables de instancia son todas aquellas que no son precedidas por la palabra reservada static
  • final
    • Usada para definir una variable inmutable o constante

Con lo que mencione antes contesto parcialmente las preguntas planteadas al inicio, a excepción de: Existe una diferencia entre lo estático y lo de instancia? Veamos el siguiente ejemplo:

class Perro{
  static String amo = "Carlos";
  String nombre;
  int edad;
  Perro(String nombre, int edad){
    this.nombre=nombre;
    this.edad=edad;
  }
  void quienEres(){
    System.out.println("Me llamo "+this.nombre+", tengo "+this.edad+" años y mi amo es "+this.amo);
  }


  void cambiarAmo(String amo){
    this.amo=amo;
  }


  public static void main(String args[]){
    Perro firulais = new Perro("firulais",2);
    Perro cuco = new Perro("cuco",5);
    Perro fumanchu = new Perro("fumanchu",3);

    firulais.quienEres();//Me llamo firulais, tengo 2 años y mi amo es Carlos
    firulais.cambiarAmo("Jose");//Cambiemos el amo...
    cuco.quienEres();//Me llamo cuco, tengo 5 años y mi amo es Jose
    fumanchu.quienEres();//Me llamo fumanchu, tengo 3 años y mi amo es Jose
  }

}


Para ver el código en acción pueden visitar mi Ideone.

Podemos ver que si cambio el amo del perro firulais, también se cambia el amo a cuco y fumanchu, esa es la diferencia entre estático e instancia, lo estático es todo aquello que sirve a nivel de clase, no de objeto, por lo tanto si se modifica un atributo, se va a modificar para todos los objetos creados o a crear, mientras que los atributos de instancia son únicos para cada objeto, es decir, si modifico un atributo no estático o de instancia en el objeto a, el objeto b no se va a ver afectado.

Es importante diferenciar a la perfección lo que es estático y lo de instancia así que si todavía tienen dudas, pueden preguntarme a mi o buscar en google acerca de estas diferencias; Ya que esto se vuelve crucial mas adelante.

//Se enjuaga antes de secar?

Bien para reforzar mas mi punto, hay que entender el orden de ejecución en Java, normalmente se nos dice que el método main es el primero que se ejecuta, pero es no es cierto! antes del main se ejecuta otro bloque o bloques, los bloques estáticos...veamos la siguiente clase:

class OrdenEjecucion{
 static {
  System.out.println("Bloque estatico!");
 }

 public static void main (String[] args) throws java.lang.Exception
 {
  System.out.println("Metodo Main");

 }
}


Al igual que en bloques anteriores pueden ver la ejecución en mi Ideone. Si ejecutan este código no solo compila, si no que también se ejecuta, los invito a correrlo para ver el resultado, pero si son algo desesperados como yo, les presento el resultado:

Bloque estatico!
Metodo Main

Pero que pasa con los objetos? Bueno ahora les pondré el flujo con bloques de instancia:

class OrdenEjecucion2
{

 static {
  System.out.println("Bloque Estatico");
 }

 {
  System.out.println("Bloque de Instancia");
 }

 OrdenEjecucion2(){
  System.out.println("Constructor");
 }

 public static void main (String[] args) throws java.lang.Exception
 {
  System.out.println("Metodo Main");
  new OrdenEjecucion2();
 }
}


Aquí esta el link a mi Ideone, pero como antes el resultado de correr  esta clase sera:

Bloque Estatico
Metodo Main
Bloque de Instancia
Constructor

Ahora vistos estos ejemplos creo ya se dan una idea del orden de ejecución en Java:

  1. Inicializacion de variables estáticas
  2. Ejecución de bloques estáticos
  3. Ejecución del método main
  4. Inicializacion de variables de instancia
  5. Ejecución de Bloques de Instancia
  6. Ejecución del Constructor
Cabe mencionar que del punto 4 al 6 la ejecución puede ejecutarse o no y también puede cambiar de orden, dependiendo donde se haga se instancie el objeto, es decir, si el objeto se instancia antes de la lógica del método main, entonces primero se ejecutaran del 4 al 6 antes de la lógica del método main (3), pero eso no quiere decir que entre primero del 4 al 6 antes que al 3; entra al 3 y por el orden de nuestra lógica ejecuta primero la lógica del 4 al 6 antes que toda la lógica del 3. Podemos ver un ejemplo mas completo a continuación:

class OrdenEjecucionCompleto{

 static int num1 = 5, num2 = 23;
 int num3 = 14, num4 = 9;
 static{
  new OrdenEjecucionCompleto();
  System.out.print("Bloque Estatico \n num1 + num2 = ");
  System.out.println( num1 + num2 );
 }

 {
  System.out.print("Bloque de Instancia \n num1 + num3 = ");
  System.out.println( num1 + num3 );
 }

 public static void main (String[] args) throws java.lang.Exception
{
  System.out.print("Metodo Main \n num2 - num1 = ");
  System.out.println( num2 - num1 );
 }

 OrdenEjecucionCompleto(){
  System.out.print("Constructor \n num4 + num3 = ");
  System.out.println( num4 + num3 );
 }


Pueden ejecutarlo en mi Ideone, y como he dicho con anterioridad, el resultado de ejecutar esta clase sera:

Bloque de Instancia 
 num1 + num3 = 19
Constructor 
 num4 + num3 = 23
Bloque Estatico 
 num1 + num2 = 28
Metodo Main 
 num2 - num1 = 18

Como pueden ver La ejecución cambio, debido a que en la primera linea de mi bloque estático instancie mi Objeto, el bloque de instancia y el constructor se ejecutaron primero que el método main y antes de la lógica del bloque estático. Como pueden darse cuenta, podemos escribir nuestros programas sin necesidad del método main o del constructor**, podemos utilizar puros bloques estáticos y de instancia.

** Si no se declara explicitamente el constructor, Java añade un constructor vacio, ya que no pude existir una clase sin su constructor.

//Conclusión

Como dije al inicio de este post, mi objetivo no es cambiar su opinión de Java, por lo contrario, mi objetivo es que conozcan un poco mas de Java, conocer lo que regularmente nunca se dice en un salón de clases o en un libro.

Durante este post hable mucho de bloques estáticos y de instancia y de como estos pueden ser utilizados, pero porque digo que Java es un lenguaje de bloques y no de Objetos? simple, un Objeto no es mas que un bloque de instancia que internamente en memoria apunta al constructor y el método main no es mas que un método estático referenciado por el nombre main que internamente la JVM lo entiende como el método principal:

public static void main(String args[]){
    //TODO
}

constructor(){
    //TODO
}


En los extractos anteriores pudieron darse cuenta que el main no es mas que un bloque estático, y el constructor es un bloque de instancia, pero como lo mencione con anterioridad esto no significa que Java no siga el paradigma OO, con Java efectivamente se pueden "crear" Objetos de la vida diaria programaticamente, solo tengan en mente que Objeto = Instancia de Constructor = Bloque de Instancia referenciado en memoria al Constructor y que main = Bloque Estático referenciado internamente en memoria a un método llamado main.

Bueno chavos, sin mas por el momento me despido, espero que esto les haya sido de utilidad y pues cualquier duda o comentario, pueden dejarlo en la sección designada para eso, sin mas por el momento me despido, adiós ^_^/

Comments

  1. me parecio interesante lo del orden de ejecucion de la JVM, a decir verdad me impreciono bastante, cambio mi forma de ver java ya que como dijiste antes a los estudiantes nos traumatizan con que el main es lo primero que ejecuta la JVM jajaja. saludos.

    ReplyDelete

Post a Comment

Popular posts from this blog

Juego de Gato Usando HTML, JavaScript y CSS

AfterEffects - Quitar el Fondo de un Video Forma 1: KeyLight

Crear un nuevo Libro de Excel con VBA ES