[Las cosas que no interesan]

pageicon viernes feb 03, 2006

No pasa hasta que pasa

Hay unas pocas cosas en la vida que uno no necesita que le demuestren, no necesita demostrarlas y suelen convertirse como toda verdad, en una "mentira pactada". A veces una mentira pactada entre un grupo de amigos o un grupo de estudio; a veces un país o un continente; pero generalmente es entre mi cerebro y yo. Hay mentiras de esas que se necesitan para vivir, muchos lo dicen de Dios; otras son necesarias para sentirse buena persona, "no, el dinero no es lo único que me importa en la vida", es una de esas bastante utilizada.

Pero hay otro tipo de "mentiras pactadas" y al parecer se hacen mientras se duerme o mientras me despisto mirando la colita peluda de un perro; son esas mentiras que no sabemos de donde salieron, como estar seguro que la capital de Brasil es Vietnam o que Pepe Granados es un gran escritor, sin haberlo leído ni escuchado hablar de él nunca.

Recuerdo que alguna vez conversaba con un gran amigo sobre las cosas que íbamos a procurar hacer durante los siguientes cinco años. Mi amigo decía que se iba a dedicar a escribir literatura, pero no cualquier literatura; se trataba de hacer libros que sobresalían por extensos y tratar temas sin ninguna importancia ni sentido aparente, por ejemplo, dedicar un libro de 500 páginas a esa rasquiña (comezón) que a veces nos da en la espalda. La idea principal del su literatura era no esforzarse mucho, escribir lo primero que llegue a la cabeza y concentrarse en lograr esas 500 páginas. La verdad, la idea me pareció maravillosa, yo quería comprar esos libros, Daniel Samper y Julio Cortázar han hecho cosas maravillosas (mucho más cortas) basados, excepto, por la extensión del texto, en una idea similar. Claro, mi amigo ni siquiera es bueno para leer.

Después de escuchar semejante maravilla, no me quería quedar atrás y también hice mi propósito para los siguientes cinco años; se trataba pues de ser capaz de responder cualquier pregunta pero si no conocía la respuesta, la inventaba rápidamente, y para tratar de despistar al enemigo inventaba una serie de datos al respecto que dejaran al "preguntante" sino satisfecho, al menos confundido. Veamos un ejemplo para mayor claridad:

Preguntante: Pepe, ¿cuál es la capital de Brasil?

Pepe: La capital de Brasil es Vietnam.

Preguntante: mmm, Pepe, no estoy muy convencido de su respuesta, creo que la capital de Brasil se llama Brasilia y ¿Vietnam no es un país? ¿De esos que compiten con el café de Colombia?

Pepe : mijo, la capital de Brasil es Vietnam, claro que Vietnam también es un país africano, pero resulta que en Junio de 1762 (dar fechas siempre es bueno) hubo una reforma del Partido Nacional Brasileño en la cuál se adoptó Vietnam como nombre para la capital brasileña, entre otras cosas por que Brasil también es un país cafetero (usar datos verdaderos ayuda a la confusión). La reforma fue bien aceptada por los polos democráticos, pero hubo un grupo no muy de acuerdo con el nombre y decidió tomarse el poder con las armas en el año de 1766; lo alcanzó y volvió a adoptar Brasilia (noten como uso el dato que me dio el preguntante para usarla dentro de mi respuesta) pero constitucionalmente el cambio nunca se hizo, así que según las vías legales la capital de Brasil es Vietnam y quienes afirman que es Brasilia, técnicamente están cometiendo un error.

Preguntante : entiendo, pero ¿Vietnam es un país africano?, creía que quedaba en Asia.

Pepe: Sí mi querido preguntante, en África central hay una zona bastante desconocida, caracterizada por la gran cantidad de ...

De esta manera logro dar respuesta a cualquier pregunta que me formulan; es necesario dominar la dialéctica para construir mi respuesta a partir de las aseveraciones que me hacen los preguntantes, pero en general me ha ido bien.

¿A dónde quiero llegar?

Bien, hay dos cosas de las que nunca tuve duda en Java, nunca me las demostraron o las demostré, solamente me parecían muy obvias y demostrarlas significaba perder el tiempo que podía usar inventando maravillosas respuestas.

1. De los métodos estáticos y como evitar que los hijos cometan nuestros mismos errores:

Una de ellas es que los métodos estáticos no se heredaban ni se podían sobrescribir, que solamente se trataba de ubicar una porción de código en cierta clase; igual no tienen acceso a los atributos de instancia, por lo que no interactúan "directamente" con la clase. Tampoco se me habría ocurrido nunca nombrar un método estático en una clase con el mismo nombre de un método estático implementado en el papá. Para mí las cosas estáticas generalmente suenan a utilidades y según este razonamiento, una utilidad la hace el papá o el hijo, nunca ambos.

Pues vaya susto me llevé esta semana cuando resultó una pregunta en la que había que seleccionar dos implementaciones correctas para un método principal (main()), los ganadores fueron:

public static void main(String arg[]){}

final Public static void main(String arg[]){}

El descubrimiento comenzó cuando afirmé a ojo cerrado (como afirmando que dos más dos es cuatro) que ambos métodos eran implementaciones válidas y que en la práctica no había ninguna diferencia entre los dos. Menudo planchazo (como algún día leí por acá) me he pegado cuando me demuestran que eso no es cierto y que los métodos estáticos como cualquier otro se heredan, se pueden sobrescribir y que marcar un método estático como final hace que los hijos de esa clase no puedan tener un método con la misma firma, ni estático ni de instancia. En la práctica, esto quiere decir que:

public class Demonstration {
	final static void metodo(){}
}
class Clase extends Demonstration{
	static void metodo(){}
}

Es algo que no compila, pues el método estático metodo de la clase Demonstrationestá marcado como final.

La verdad es que aún no he visto la necesidad prohibir a un hijo implementar mis métodos estáticos.

2. De los atributos de instancia y como el casting puede ayudar a conocer mejor nuestro padre:

Sabemos que en java todo se trata de apuntadores y lo único seguro que tenemos es que una variable apunta hacia un objeto que cumple la condición IS-A (es un) con su tipo de dato. Por ejemplo en este trozo de código en donde Pepe

Pepe pp = demeUnPepe();

Lo único que nos deja claro es que pp apuntará hacia un objeto que cumple la condición IS-A Pepe (es un Pepe) y nada nos asegura que ese objeto sea una instancia directa de Pepe

También es claro que los métodos que vamos a invocar son los del objeto al que estamos apuntando y que los valores a los que se acceden son a los contenidos en ese objeto. Al menos para mi era claro. Pero hay otra cosa que hoy me demostré por contraejemplo, por contraejemplo por que lo que hice fue derrumbar una hipótesis que yo había asumido más no demostrado. ¿De qué se trata? veamos:

public class Prueba {
    public static void main(String[] args) {
          Clase clase = new Clase();
          System.out.println(Integer.toHexString(clase.valor));
    }
}
class Una{
    int valor = 0xC0C0;
}
class Clase extends Una{
    int valor = 0xCACA;
}

Al compilar y ejecutar este código, espero que la salida sea caca, en eso no hay problema, es lo que obtengo. En el método principal creo una variable de tipo Clase que queda apuntando hacia una instancia también de tipo Clase; por supuesto el valor de la variable valor en Clase es 0xCACA (en hexadecimal) y por eso la salida no ha de sorprendernos.

La clase Clase hereda la clase Una, por tanto podemos crear un objeto de tipo Clase pero apuntar a él con una variable de tipo Una, sin embargo lo que solía pensar es que se sigue apuntando a los atributos y métodos de la instancia de Clase, por lo que la salida no debería cambiar:

public class Prueba {
    public static void main(String[] args) {
          Una clase = new Clase();
          System.out.println(Integer.toHexString(clase.valor));
    }
}
class Una{
    int valor = 0xC0C0;
}
class Clase extends Una{
    int valor = 0xCACA;
}

Note que el único cambio fue el tipo de la variable clase, la instancia sigue siendo la misma, por que yo esperaba una salida igual a la anterior, es decir caca. ¿Pero qué sucedió?, pues al compilar y ejecutar obtuve: c0c0.

Vaya mierda, esperaba caca y obtuve c0c0; ¿por qué?, pues resulta que al parecer cuando vamos a ver el valor de una variable de instancia si es importante el apuntador que estemos usando. Como estaba usando una variable de tipo Una, de allí obtuvo el valor de la variable valor.

¿Qué hay con los métodos?, pues nada, se ejecutan los que contiene la instancia, es decir, aunque el apuntador sea de tipo Una, se van a ejecutar lo métodos implementados en la clase Clase. ¿Por qué con los atributos no es igual?, pues no tengo ni idea del por que este aparentemente complicado funcionamiento.

¿Qué pasó? ¿Qué se puede concluir? ¿Qué a veces es necesario prohibir que mis hijos hereden mi comportamiento estático? ¿Qué hay ocasiones en la vida en las que uno espera caca y recibe c0c0? ¿Algún día voy a esperar c0c0 y a recibir caca? ¿Qué eso de inventar respuestas a lo desconocido se está volviendo contra mí y ahora mientras mi cerebro derecho duerme el izquierdo le inventa respuestas?

Pues no se. Por ahora a aprovechar que Miguel Abián publicó una versión actualizada de su tutorial sobre programación orientada a objetos, a lo mejor acá me aclaran el por qué de los métodos estáticos. También por lo que veo hay que acudir a las especificaciones del lenguaje para aclarar la otra situación.

Tengo la sensación que la teoría de la programación orientada a objetos es una interfaz que implementa Java, y creo que no es suficiente conocer las interfaces; la implementación nos muestra mucho de un mundo que debió ser pero no se pudo.

Eso sí, no puedo negar que esto me hacer recordar la agradable sensación que se siente cuando se está aprendiendo un nuevo lenguaje y funciona el hola mundo; o esa misma sensación que sentí cuando hice un compilador que funcionaba, y es que esto de programar es como dar vida a las aves de barro.

Comentarios:

Enviar un comentario:
  • Sintaxis HTML: Deshabilitado