Slider Image

  • Google Chrome

    Tips, extensiones y trucos para aprovechar al máximo tu navegador Chrome

  • HTML5

    Conoce la nueva versión del lenguaje de programación web por excelencia

  • Java

    Aprende a programar en Java con tutoriales paso a paso, cubriendo desde lo más básico hasta lo más especializado

  • NetBeans

    Conoce este completo IDE para desarrollar en diversos lenguajes, aprende trucos y conceptos que te facilitarán la codificación de cualquier tipo de software

  • Linux

    ¿Eres linuxero o deseas serlo? Hay una sección especialmente para ti.

  • Ahora Mis Ojos Te Ven

    Echa un vistazo a mi nuevo blog 'Ahora Mis Ojos Te Ven' y no dudes en dejarme tu opinión.

Constructores sobrecargados

Sobrecargar un constructor significa escribir versiones múltiples del constructor de una clase, cada uno de ellos con una lista diferente de argumentos, algo parecido a lo que se muestra a continuación:

 

class Animal{

 

  Animal(){}

 

  Animal(String nombre){}

 

  Animal(String nombre, int edad){}

 

}

 

En la clase anterior (la clase Animal) podemos identificar que existen 3 constructores sobrecargados, uno que toma una cadena como argumento, otro que toma una cadena y un entero y otro sin argumentos. Debido a que el constructor sin argumentos actualmente no contiene código es igual al constructor por defecto que provee el compilador de forma automática, pero debido a que ya existe otro u otros constructores en la clase, el compilador no agregará un constructor por defecto de manera automática.

 

Sobrecargar un constructor es típicamente utilizado para proveer a los clientes formas alternas de instanciar objetos de la clase. Por ejemplo, si el cliente sabe el nombre del Animal, puede pasarlo como argumento por medio del constructor que toma una cadena pero no si lo sabe puede crear el objeto Animal utilizando el constructor sin argumentos.

 

Si existen diversos constructores para una clase debemos de tomar en cuenta que lo que determina qué constructor se llamará una vez que se crea el objeto o se utiliza la palabra clave 'new' es precisamente los argumentos que pasamos, por ello, no pueden existir múltiples constructores con la misma lista de argumentos.

 

Otro punto a tomar en cuenta (que ya he mencionado en el artículo anterior sobre constructores) es que un constructor nunca NUNCA podrá devolver nada, ni siquiera void, si se llega a encontrar algo como esto...

 

class Animal {

 

  void Animal(){} //No es un constructor, es un método

 

  Animal(String nombre){} //Constructor!

 

}

 

...estamos hablando de un método que tiene el mismo nombre de la clase que devuelve un valor tipo void y de un constructor que acepta como argumento un valor tipo cadena.

 

Hasta aquí llegamos con constructores sobrecargados. Alguna duda o algo qué decir? Deja tu comentario. Saludox.

 

Los constructores y la creación de instancias

Para comenzar a analizar la creación y el comportamiento de los objetos en Java debemos de partir de la premisa de que 'todos los objetos se construyen'. Para que se entienda un poquito mejor, los constructores son aquel bloque de código que se manda a llamar cada vez que el compilador encuentra la palabra 'new' dentro del código. No se puede crear un objeto sin invocar primeramente a su constructor. De hecho, no se puede crear un nuevo objeto no solo sin invocar a su constructor sino a todos los constructores de todas sus clases padre o superclases.

 

Tomando en cuenta la información anterior, vamos a comenzar con algunos conceptos básicos sobre los constructores.

 

Conceptos básicos de los constructores::

 

Cada clase, incluyendo las clases abstractas, deben de poseer un constructor. Pero solo por el hecho de que cada clase debe de tener alguno no significa que el programador debe de escribirlo. Un constructor se ve más o menos así:

 

class MiClase{

 

  MiClase(){ } //Constructor de la clase

 

}

 

Dos cosas importantes a recordar sobre los constructores:

  * No poseen un tipo de retorno.

  * Deben de llamarse exactamente como la clase.

 

Los constructores típicamente se utilizan para inicializar variables de instancia de la clase como se muestra en el siguiente código:

 

class MiClase{

 

  int tamano;

  String nombre;

 

  MiClase(int tam, String nom){

    tamano = tam;

    nombre = nom;

  }

 

}

 

Si observamos el código anterior podemos notar que la clase MiClase no posee un constructor sin argumentos, lo que significa que el siguiente código provocaría un error al compilar:

 

MiClase mc = new Miclase(); //Error! no hay un constructor sin argumentos

 

Pero el siguiente código compilará sin errores:

 

MiClase mc = new MiClase(5,"Nombre"); //los argumentos coinciden con el constructor

 

Es muy común (e incluso deseable) que cada clase posea un constructor sin argumentos, independientemente de cuántos otros constructores sobrecargados existan (claro que los constructores pueden sobrecargarse, igual que los métodos).

 

Encadenamiento de constructores::

 

Ya sabemos que los constructores se invocan en tiempo de ejecución cuando encuentran la palabra clave 'new' dentro del código...

 

Caballo c = new Caballo();

 

Pero lo que sucede realmente cuando se encuentra 'new Caballo()' es lo siguiente (asumiendo que Caballo hereda de Animal y Animal hereda de Object):

 

1. El constructor de la clase Caballo es invocado. Cada constructor invoca al constructor de su clase padre con una llamada implícita a super(), a menos de que dicho constructor invoque a un constructor sobrecargado de su misma clase.

 

2. El constructor de la clase Animal es invocado (ya que Animal es la clase padre de Caballo).

 

3. El constructor de la clase Object es invocado (ya que Object es la clase padre última de todas las clases, todos los objetos heredan de Object, así que Animal hereda de Object aún cuando no has escrito Animal extends Object).

 

4. Las variables de instancia de la clase Object son asignadas a sus valores explícitos. Los valores explícitos son aquellos que son definidos al momento de que las variables son declaradas, como 'int i = 0;', donde '0' es el valor explícito de 'i'.

 

5. El constructor de la clase Object es completado.

 

6. Las variables de instancia de la clase Animal son asignadas a sus valores explícitos.

 

7. El constructor de la clase Animal es completado.

 

8. Las variables de instancia de la clase Caballo son asignadas a sus valores explícitos.

 

9. El constructor de la clase Caballo es completado.

 

En resumen:

 

1. main() llama new Caballo() -> 2. Caballo llama super() -> Animal llama super() -> Object()

 

Para terminar con este tema, veamos las reglas para los constructores.

 

Reglas para los constructores::

 

1. Los constructores pueden utilizar cualquier modificador de acceso, incluyendo 'private'.

 

2. El nombre del constructor debe de coincidir exactamente con el de la clase.

 

3. Los constructores no deben de tener un tipo de retorno.

 

4. Es legal, pero no es recomendable, el tener un método con el mismo nombre de la clase, pero eso no lo hace un constructor.

 

5. Si no se crea manualmente un constructor dentro del código de la clase, un constructor por defecto será generado automáticamente por el compilador.

 

6. El constructor por defecto SIEMPRE es un constructor sin argumentos.

 

7. Si se desea un constructor sin argumentos y se ha creado otro u otros constructores, el compilador no creará uno por defecto.

 

8. Cada constructor tiene como primer sentencia ya sea una llamada a un constructor sobrecargado de la misma clase (this()) o una llamada al constructor de su clase padre (super()), sin embargo, esta llamada puede ser insertada automáticamente por el compilador.

 

9. Si no se crea un constructor manualmente, y no se llama manualmente a super() o this(), el compilador insertará una llamada sin argumentos a super() como primer sentencia dentro del constructor.

 

10. Una llamada a super() puede ser ya sea sin argumentos o puede incluir argumentos pasados al constructor sobrecargado de la clase padre.

 

11. No se puede hacer una llamada a un método de instancia, o acceder a una variable de instancia sino hasta después de que el constructor de la clase padre (super()) se haya ejecutado.

 

12. Sólo variables y métodos estáticos pueden ser accedidos como parte de una llamada a super() o this().

 

13. Las clases abstractas poseen constructores, dichos constructores son llamados siempre que una subclase concreta es instanciada.

 

14. Las interfaces no poseen constructores.

 

15. No se puede invocar un constructor directamente desde un método o alguna otra parte del código que no sea otro constructor. En pocas palabras, no se puede hacer lo siguiente:

 

class Caballo{

 

  Caballo(){} //Constructor

 

  void metodoDeClase(){

    Caballo();  //ilegal!

  }

}

 

Listo, hemos terminado con los constructores. Espero haber dejado claro el tema. Alguna duda o algo qué decir? Deja tu comentario. Saludox.

Atajos del teclado en NetBeans 6.0

Algunos atajos del teclado bastante útiles en NetBeans 6.0:

 

NetBeans ShortCuts

Atajo

Función

Sirve para…

Ctrl + Space

Code Completion

Agregar constructores, usar métodos de clase, extends, implements

Alt + Insert

Code Generator

Agregar getter's y setter's, equals() y hashcode(), override, etc

Alt + Enter

Manage Imports, surround

Agrega los import's necesarios, remueve los no utilizados, envuelve sentencias con if, for, do, try, etc

Ctrl + Shift + (flecha Arriba o Abajo)

Editor line tool

Copia las líneas seleccionadas hacia arriba o abajo

Alt + Shift + (flecha Arriba o Abajo)

Editor line tool

Mueve las líneas seleccionadas hacia arriba o abajo

Ctrl + R

Rename

Con el cursor sobre el identificador, renombra todas las ocurrencias

Alt + Shift + (Coma, Punto)

Selection editor

Expande o contrae la selección de código por bloques definidos

 

Fuente | NetBeans.org

Cuidado con los mensajes por cobrar de Movistar

Hace un rato, recibí un mensaje de Movistar que decía lo siguiente:

"Tienes un mensaje Movistar por cobrar de 6621646932. Para recibirlo, responde a este mensaje con el texto 'si'. Precio $1.50.

De: +520346621646932"

En seguida traté de localizar información con respecto a este tipo de mensajes en internet pero no encontré nada de relevancia así que decidí ver lo que sucedía al seguir las instrucciones del mensaje, por lo tanto, respondí al mismo con la palabra si. Inmediatamente después me llegó un mensaje en 3 partes diciendo lo siguiente:

 

"BOLETAZO"
'URGENTE'
Estimado Cliente Hoy se Realizo el Sorteo # 39 Que Realiza "BOLETAZO" en Apoyo a @SALVATION@ Donde su Linea. Es Ganadora del Automovil JETTA (100.00 pesos M.N) y un Equipo Tel/Cel. "Mil Felicidades" Comunicate a la Cd. de Mexico. al 0456621631290 lic. ALFREDO ESCOVAR GUTIER" Responde pagale otro mensaje Precio $2.00. Si envias uno nuevo solo pagas tu mensaje.

 

Anteriormente ya había recibido mensajes tratando de hacerme caer en una estafa, afortunadamente cada día se hace más difícil el que personas como las que me mandaron este mensaje puedan aprovecharse de la gente gracias a que los medios de comunicación han tratado de hacerle sabernos saber lo que implica un mensaje o llamada de este tipo. Claro que no llamé al teléfono indicado en el mensaje, pero si quieres saber lo que sucede en una llamada de estas te invito a leer el artículo Fraudes telefónicos Exposed de Héctor López, fundador y director de la OHME, donde hay conversaciones grabadas con estos delincuentes.

 

Lo que me sorprende de esta ocasión en particular es que los estafadores ya ni siquiera se toman la molestia de 'invertir' saldo en sus mensajes, sino que ya hasta te hacen llegar una 'estafa por cobrar' aprovechándose de la posibilidad que les otorga Movistar de realizar enviar los mensajes de esa manera, la verdad es que esto me molesta bastante, ¿cómo es posible que gente tan ruín haga este tipo de cosas?, no cabe duda que no son personas, son Animales, las personas nos ganamos la vida con nuestro trabajo honrado, no engañando o tratando de engañar a los demás, estos animales no me causan más que repudio y asco.

Mi recomendación es que no contestes a estos mensajes si no conoces el número que se te indica en el mismo, no les des el gusto a estos animales de pagar por un mensaje asqueroso y con malas intenciones.

Te invito a difundir esta información para evitar que estos delincuentes cumplan con su cometido.


Algo que decir? Deja tu comentario. Saludox.

 

Un momento musical

 

Rescatar información de una computadora con Windows dañado

El día de ayer un vecino que es arquitecto llegó a mi casa a pedirme que le hiciera el favor de arreglar su computadora ya que ésta se había quedado inutilizable después de querer instalar Autocad 2008, el problema era que al arrancar le aparecía una de esas fabulosas pantallas azules del sistema operativo Windows XP indicándo un error. Me comentó que tenía mucha información valiosa (entre ella estaba su tésis, clásico) y que hiciera todo lo posible por rescatar dicha información localizada como de costumbre en la carpeta de 'Mis Documentos'. Le dije que me dejara su equipo, que haría todo lo posible por ayudarlo y él agradecido se fue.

Una vez que él se fue me di a la tarea de conectar su computadora para primeramente inspeccionar la situación de la misma, al encenderla me di cuenta de que efectivamente, había quedado inutilizable, no importa en qué modo de operación se tratara de encender (normal, modo seguro, última configuración buena conocida, etc), el error era siempre el mismo: UNMOUNTABLE_BOOT_VOLUME.









No soy un experto en esto de qué significa cada error de Windows, y no se por qué apareció éste error al tratar de instalar el Autocad, simplemente entiendo que si hay una pantalla azul al enceder existe un problema grave y lo más seguro es que se necesite una reinstalación completa del sistema.

La primera tarea era rescatar la información que tenía en el ahora dañado sistema. Lo primero que hice fue ingresar al BIOS y verificar las características del equipo, eran 128 RAM (probablemente por eso tronó al querer instalar el Autocad, aunque en teoría no debería de hacerlo), 40 Gb de disco y un procesador Intel Celeron a 1.80 GHz.

Posteriormente analicé la posibilidad de arrancar con un live cd de Linux, montar las unidades de disco y rescatar la información (algo que suelo hacer con frecuencia), pero las características del equipo no me eran suficientes para trabajar con fluidez bajo el live cd de Ubuntu (que es el que normalmente utilizo) y opté por utilizar Wifislax, una distribución que conocí gracias a un artículo de Linuxman sobre la auditoría de redes inalámbricas, dicha distribución es ligera, arranca rápidamente y provee de muchas utilidades de red sumamente interesantes, además posee una interfaz gráfica tipo Xwindow.

Ya dentro de Wifislax analicé las unidades de disco conectadas a la tarjeta madre desde la terminal con el comando fdisk -l, lo que me arrojó algo parecido a lo siguiente:

.
.
Device Boot Start End Blocks Id. System
/dev/hda1 * 1 3310 26587543+ 7 HPFS/NTFS
.
.

Posteriormente hice una carpeta dentro de /media con el nombre DD y monté la unidad de disco en dicha carpeta:

root@wireless# mkdir /media/DD
root@wireless# mount -a /dev/hda1 /media/DD

Una vez hecho esto todos los archivos contenidos en el viejo sistema estaban disponibles desde la ruta /media/DD.

Ingresé a la carpeta de 'Mis Documentos' del usuario que manejaba mi vecino y verificando las propiedades de la misma me di cuenta que su tamaño era de 2.5 Gb, y en ello encontré otro problema, no tengo una memoria USB tan grande, solo la del celular y es de 1Gb, tendría que pasar en 3 tantos la información lo que implicaría bastante tiempo, la computadora tenía quemador de cd y dvd pero estaba siendo utilizada por el live cd de Wifislax, solo tenía un disco duro por lo que no podría conectar otro como esclavo para copiar la información, mi computadora es portátil y el disco duro no es compatible con la de escritorio, pude haber creado una red entre Wifislax (pc de mi vecino) y Ubuntu (mi portátil) a través del router 2Wire de infinitum que tengo (ya que tampoco contaba con un cable cruzado para hacerlo directamente) pero sinceramente no tengo mucha experiencia en ello y me tardaría bastante aprendiendo y aplicando.

Al final, analizando las utilidades de Wifislax me di cuenta que contaba con un cliente FTP, gFtp y comencé a ver la luz. Contando ya con el cliente solo me faltaba el servidor, así que ingresé a Apache Friends y descargué el XAMPP en mi portátil, que cuenta con FileZilla, un servidor FTP, seguí las instrucciones de instalación y activé el servidor FTP en el puerto 21.











Ya con el cliente y el servidor intenté conectarme desde Wifislax pero no me fue posible, me indicaba un error de red inaccesible, lo primero que pensé fue en el muro de fuegos e ingresé a la configuración del router 2Wire y abrí el puerto 21 para ambos equipos en TCP, después intenté la conexión nuevamente con el usuario anonymous y listo!! ya tenía comunicación entre ambos equipos, lo único que faltaba era copiar los archivos de un lugar a otro. Intenté ahora la copia y apareció otro error de permisos de usuario, así que ingresé a la configuración del servidor ftp desde .../xampp/filezilla y le di permisos de escritura y creación de directorios al usuario anonymous. Intenté nuevamente la copia y listo!! todo sin problemas, se estaban copiando los archivos y rápidamente terminó la transferencia ya que se trabajó a una velocidad promedio de 1.5 Mb/s.

Nota: Cuando se utiliza la cuenta anonymous la carpeta donde se alojan los archivos por defecto es .../xampp/anonymous/incoming.

Al final de cuentas, sí me tardé un poquito configurando y resolviendo los pequeños inconvenientes que iban surgiendo, pero me resultó entretenido y divertido realizar las cosas así, supongo que para la próxima me tardaré un poco menos.

Alguna duda o algo qué decir? Deja tu comentario. Saludox.

Mamá te espera, siempre te espera

Este video llegó a mi correo gracias a una de esas cadenas, una que vale la pena (ya que aproximadamente el 90% de esas cadenas no lo valen) y realmente me puso a pensar.

 

 

Hace poco en la ciudad donde vivo, León Gto, un joven que viajaba en su Mustang a un poco más de 180 km/hr por un boulevard influenciado por los efectos del alcohol provocó la muerte de uno de sus amigos, no cualquier tipo de muerte, su amigo murió degollado, mientras sus mamás los esperaban en sus casas.

 

Tengamos conciencia de lo que estamos haciendo, no nos jugamos una coca o una 'cheve', no nos jugamos solo nuestra vida sino la de los que nos rodean y de las personas a las que apreciamos.

 

Algo que decir? Deja tu comentario. Saludox.

Ubuntu Hardy Heron dentro de muy poco

 image 

Es cierto que últimamente casi no he publicado nada con respecto a mi sistema operativo favorito: Ubuntu.

 

La verdad es que ya casi casi solamente utilizo el equipo que tengo en mi lugar de trabajo y pues, como en la gran mayoría de las empresas, trabajo con Güindous Equispe, lo que reduce la posibilidad de que yo hable más acerca de mi queridísimo Linux.

De cualquier manera no quise dejar pasar la oportunidad de decir que faltan únicamente 6 dias para que la próxima versión LTS (soporte a largo plazo) de Ubuntu, es decir,  Hardy Heron llegue con su versión definitiva.

Gracias a Canonical tenemos nuevamente el envío de cds de forma gratuita directamente a tu domicilio, de igual manera todo el software contenido en esta distribución es gratis, también podremos descargarlo, distribuirlo, copiarlo y reutilizarlo sin problema alguno gracias a su licencia de uso libre.

 

Canonical mantiene su promesa:

  • Ubuntu será siempre libre de cualquier cargo, incluyendo las ediciones empresariales y actualizaciones de seguridad.
      • Ubuntu viene con soporte comercial completo por parte de Canonical y de cientos de compañías alrededor del mundo.
      • Ubuntu incluye las mejores traducciones y la infraestructura de accesibilidad que la comunidad del software libre puede ofrecer.
      • Los cd's de Ubuntu contienen únicamente aplicaciones de software libre; nosotros te motivamos a utilizar el software libre y de código abierto, a mejorarlo y a transmitirlo.

En fin, una filosofía que comparto al 100% y una de mis principales motivaciones para utilizar, promover y distribuir el software libre.

Ya falta poco, muy poco...

Reglas para valores de retorno de métodos en Java

Todos los programadores estamos familiarizados con el uso de funciones y métodos en cualquier lenguaje de programación, sabemos que normalmente se puede (o no) recibir uno o más valores y devolver (o no) a su vez uno o más valores (dentro de un arreglo).

En Java existen algunas reglas al momento de devolver un valor por medio de un método. Las reglas son pocas, relativamente sencillas pero sumamente importantes y se listan a continuación:

1. Se puede devolver un valor null en un método con una referencia a un objeto como tipo de retorno:

public Button hacerAlgo(){
return null;
}

2. Un arreglo es un tipo de retorno perfectamente legal:

public String[] hacerAlgo(){

return new String[] {"hugo","paco","luis"};

}

3. En un método con un primitivo como tipo de retorno, se puede devolver cualquier valor o variable que pueda ser implícitamente convertida hacia el tipo de retorno declarado:

public int hacerAlgo(){

char c = 'c';
return c; //un char es compatible con int
}

4. En un método con un primitivo como tipo de retorno, se puede devolver cualquier valor o variable que pueda ser explícitamente convertida hacia el tipo de retorno declarado:

public int hacerAlgo(){

float f = 32.5f;
return (int) f;

}

5. No debes de devolver nada en un método que tiene void como tipo de retorno:

public void hacerAlgo(){

return "hola mundo"; //Ilegal!

}


6. En un método con un objeto como tipo de retorno se puede devolver cualquier tipo de objeto que pueda ser implícitamente convertido hacia el tipo de retorno declarado:

public Animal getAnimal(){

return new Perro; //Asumiendo que Perro extends Animal

}
Estas fueron las reglas a tomar en cuenta al momento de crear y utilizar métodos en Java.

Alguna duda o algo que decir? Deja tu comentario. Saludox.

Cómo implementar una interface en Java

Cuando se implementa una interface se está aceptando una especie de contrato definido en la interface. Esto significa que estás aceptando el proveer implementaciones legales para cada método definido en la interface.

Por ejemplo, si se crea una clase que implemente la interface Runnable (para que el código pueda ser ejecutado por un hilo específico), debes de proveer el método public void run(). De otra manera, el hilo podría querer ser ejecutado pero al momento de buscar el método que le indique qué hacer simplemente no lo encontrará por que no fue definido. Java previene este tipo de situaciones ejecutando un chequeo por medio del compilador que verifíca que cada clase que implemente una interface provea de igual manera la implementación de cada uno de los métodos contenidos dentro de esta interface.

Asumiendo la interface Rebotable, que contiene dos métodos: rebotar() y setFactorRebote(), el siguiente código de clase compilaría sin problemas:

public class Pelota implements Rebotable{
public void rebotar(){}
public void setFactorRebote(int fr){}
}

Analizando el código anterior nos damos cuenta de que la implementación se efectúa, aunque los métodos simplemente no hagan nada, con esto concluimos que la implementación de una interface garantiza la implementación de los métodos definidos dentro de ella, pero no una 'buena' implementación, o incluso que los métodos contengan alguna cantidad de código definido dentro de los mismos.

Las clases implementantes deben de seguir las mismas reglas de implementación de los métodos de una interface así como las clases que heredan a otra clase abstracta. Para realizar una implementación legal una clase no abstracta debe de obedecer a las siguientes reglas:

  • Proveer implementación concreta (no abstracta) para todos los métodos declarados en una interface.
  • Seguir las reglas de la sobreescritura de métodos.
  • Declarar excepciones no verificadas en la implementación de los métodos distintos de aquellos declarados por los métodos de la interface, o subclases de aquellos declarados en los métodos de la interface.
  • Mantener la firma de los métodos de la interface, y mantener el mismo tipo de retorno (o un subtipo del tipo de retorno).

Se debe de tomar en cuenta que una clase implementante puede a su vez ser abstracta, por ejemplo:

abstract class Pelota implements Rebotable { }

Si este fuera el caso, la clase simplemente pasa la responsabilidad de la implementación de los métodos de la interface a la primera siguiente clase no abstracta. Por ejemplo, si PelotaDePlaya es una clase no abstracta pero hereda de la clase Pelota, entonces PelotaDePlaya tiene que implementar los métodos de la interface Rebotable...

class PelotaDePlaya extends Pelota{

public void rebotar(){
//métodos que especifican el comportamiento al rebotar
//de una pelota de playa
}

public void setFactorRebote(int bf){
//métodos que especifican el factor de rebote
//de una pelota de playa
}

//Si la clase Pelota define uno o varios métodos abstractos
//deben de ser implementados por la clase PelotaDePlaya de
//igual manera que aquellos de la interface Rebotable.

}

Antes de finalizar, debemos de mencionar algunos aspectos importantes de las interfaces:

1. Una clase puede implementar más de una interface, es perfectamente legal realizar algo como lo siguiente:

public class Pelota implements Rebotable, Serializable, Runnable {
.
.
.
}

Se puede extender o heredar solamente una clase pero implementar varias interaces.

2. Una interface puede extender o heredar a una o más interfaces, pero nunca puede implementar nada.

public interface Rebotable extends Movible, Serializable {} //ok!

La clase que implemente a Rebotable debe de proveer los métodos tanto para rebotable como Movible y Serializable.


Hasta aquí le dejamos con las interfaces en Java.

Algo que decir o alguna duda? Deja tu comentario. Saludox.

Conversión(casting) de variables de referencia

Seguimos con el minicurso de Java, ahora toca el tema de conversión de variables de referencia ('Reference variable casting' por su título en el examen de certificación SCJP).

Anteriormente hemos visto cómo es posible (además de común) el usar variables de referencia de tipos genéricos para referir (valga la redundancia) a objetos de tipos más específicos por medio del polimorfismo. Por ejemplo, al hablar del siguiente tramo de código debemos de identificar que ambos tipos de objetos pertenecen al mismo árbol de herencia y por lo tanto no es extraño encontrarnos con algo así:

Animal animal = new Perro();


Ahora, ¿qué sucede si queremos utilizar una variable de referencia Animal (como en el caso anterior) para invocar a un método que solamente posee la clase Perro?. Hasta este punto sabemos que la variable de tipo Animal está conteniendo realmente un Perro, no un Animal genérico cualquiera sino un Perro específicamente. En el siguiente código representamos un arreglo de animales y, en el momento que encontremos un Perro dentro del arreglo, queremos hacer algo que solo un perro puede hacer. Acordemos entonces que todo el código siguiente está correcto excepto que no estamos seguros de la línea de código que invoca al método ladrar() que es exclusivo de un Perro...

class Animal{
void respirar(){

System.out.println("Respirando como cualquier otro animal.");
}
}

class Perro extends Animal{

void respirar(){
System.out.println("Respirando como un perro.");
}

void ladrar(){
System.out.println("Guau");
}

}

class PruebaDeConversion{

public static void main (String[] args){

Animal [] a = {new Animal(), new Perro(), new Animal()};

for(Animal animal : a){

animal.respirar();

if(animal.instanceof Perro){
animal.ladrar(); //intentando hacer comportamiento de Perro
}
}

}

}

Una vez que intentamos compilar el código anterior obtenemos un error que indica más o menos lo siguiente:

cannot find symbol
 
En pocas palabras, el compilador está diciendo 'Oye, no encuentro el método ladrar() en la clase Animal'. Para que funcione debemos de hacer algo como lo siguiente:

if(animal instanceof Perro){
Perro p = (Perro) animal; //conversión de la variable de referencia
p.ladrar();
}

El nuevo y mejorado código incluye una conversión o casting, que en este caso algunas veces es llamado 'downcast' (conversión hacia un tipo inferior) debido a que estamos descendiendo en el árbol de herencia hacia un tipo de clase más específico...

SerVivo

|

|

|

v
Animal

|

|

|

v
Perro



Con esto le estamos indicando al compilador que nosotros sabemos que se está haciendo referencia hacia un objeto de tipo Perro así que no hay problema con convertir esa variable. En este caso es seguro realizar este tipo de conversión por que previamente se verifica el tipo de referencia con instanceof.

Existen algunos casos en los que no es seguro realizar esto ya que el compilador solo verifica si realmente se trata de una referencia hacia otro tipo de objeto del mismo árbol hereditario, lo cual involucra que seamos libres en hacer algo como lo siguiente:


class Animal{}

class Perro extends Animal{}

class PerroDePrueba{

public static void main (String[] args){

Animal animal = new Animal();
Perro p = (Perro) animal; //compila pero falla después
}
}

Si realizamos lo anterior nos daremos cuenta de que compila sin errores, no debería ser así por que estamos cometiendo un error pero al final de cuentas compila, sin embargo, esto no quiere decir que la aplicación funcionará ya que al ejecutar el programa nos toparemos con algo así:

java.lang.ClassCastException


Nuevamente, el compilador lo único que puede hacer por nosotros en este caso es verificar si ambos tipos de referencia pertenecen al mismo árbol de herencia, si en el código identifica algún tipo de conversión que no cumpla con esta única condición arrojará un error. P. ejemplo:

Animal animal = new Animal();
Perro p = (Perro) animal; //compila sin problemas
String cadena = (String) animal; //Error

En este caso el error que arroja es algo parecido a lo siguiente:

inconvertible types


A diferencia del downcasting, el upcasting (conversión hacia un tipo superior en el árbol de herencia) se realiza implícitamente, lo que quiere decir que no necesitas escribir el código para realizar la conversión ya que al realizar esto solamente estarás restringiendo el número de métodos que dicho objeto puede invocar, de lo contrario al downcasting que implica una probable llamada a métodos más específicos. P. ejemplo:

class Animal {}

class Perro extends Animal{

public static void main (String [] args){

Perro p = new Perro();
Animal a1 = d; //upcast correcto sin código explícito
Animal a2 = (Animal) d; //upcast correcto con código explícito
}

}


Ambas conversiones anteriores compilan y se ejecutan sin problemas ya que Perro es un Animal, lo que implica que Perro puede hacer cualquier cosa que Animal pueda.

Por último en este tema, recordemos que código como este...


Animal a = new Perro();
Perro p = (Perro) a;
a.ejecutarMetodoDePerro();

Puede convertirse en este otro equivalente...



Animal a = new Perro();
((Perro)a).ejecutarMetodoDePerro();


Éste último es menos legible pero sigue siendo correcto.

Hasta aquí le dejamos con este tema. Alguna duda o algo qué decir? Deja tu comentario. Saludox.

JavaScript Collector: completa y útil colección de código

jscollector

JavaScript Collector es una pequeña y potente aplicación gratuita que recopila muchísimos útiles scripts de Java que están listos para copiar y pegar directamente en tu aplicación o página web.

 

Entre muchos otros contiene scripts con efectos del mouse, efectos para el fondo de la página, herramientas de correo electrónico, banners, calculadoras, efectos de texto, utilidades de fecha y hora, contadores, herramientas para el diseño web, etc, etc, etc.

 

Además de todo esto tiene la capacidad de probar los scripts en 4 navegadores diferentes(siempre y cuando los tengas instalados) sin necesidad de copiar, pegar y guardar un archivo sino directamente a través de un solo botón, incluso puedes agregar los scripts de tu colección propia para hacer una mega colección de código útil y fácil de implementar.

 

Descargar

 

Alguna duda o algo qué decir? Deja tu comentario. Saludox.

Un manual completo de HTML en español

Hace ya algún tiempo comencé a incursionar en el diseño y desarrollo de páginas y aplicaciones web y me di cuenta de que no importa en qué lenguaje desarrolles las aplicaciones (Java, PHP, ASP, etc) o diseñes las páginas(Javascript, Flash, etc)  siempre, siempre tendrás que utilizar HTML, mucho o poco pero tendrás que utilizarlo. Generalmente lo que más se utiliza son las tablas, todo mezclado con hojas de estilo y algunas otras cositas.

 

En lo personal, es muy poco lo que me meto con HTML y por ello en ocasiones tiendo a olvidar algunas cuestiones básicas del lenguaje, normalmente cuando eso sucede no queda más que ingresar a un foro o una página donde poco a poco se pueden ir disipando las dudas, es un poco tardado pero todo se resuelve a final de cuentas.

 

Un dia mientras navegaba en busca de algunas cuestiones basicas me topé con un manual bastante completo, de hecho a mi punto de vista es el mejor manual de HTML en español que hay en la red y todos mis problemas de ese tipo se resolvieron desde entonces.

 

Dicho manual aborda todos los temas necesarios del lenguaje, desde qué es HTML hasta el manejo y programación de Scripts en Java, lo mejor es que se puede descargar completito directamente al disco duro para tenerlo siempre que nos sea necesario, solamente pesa 1.4Mb así que la descarga es sumamente rápida.

 

Descargar

 

Puedes visitar periódicamente la web del autor ya que continuamente realiza actualizaciones y adiciones al manual.

 

Alguna duda o algo que decir? Deja tu comentario. Saludox.

Así se escucha el iPhone

Navegando por la red me encuentro con el tono oficial del iPhone, para todo aquel que quiera traerlo en su teléfono o simplemente escucharlo aquí lo dejo:

 

 

Descargar

 
Monillo007 © 2010 | Designed by Trucks, Manual Bookmarking | Elegant Themes