Junio 22, 2018, 08:43:10 am

Autor Tema: JAVA desde CERO  (Leído 85477 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado vVegeta

  • JavaManiaco!
  • Si te metes con CPH
    te metes conmigo
  • ****
  • Mensajes: 1791
  • Sexo: Masculino
  • I´m Unique!!... vVegeta...
    • Ver Perfil
Re: JAVA desde CERO
« Respuesta #15 en: Agosto 27, 2008, 09:31:03 pm »
Sobrecarga

En este hilo, veremos lo que es Sobrecarga... :P

Primeramente, debemos tener en cuenta las clases y métodos constructores...

Código: (java) You are not allowed to view links. Register or Login
public class MiClase
{
    MiClase()
   {
      ....
   }
}

De esta forma el método constructor se denota:

Código: (java) You are not allowed to view links. Register or Login
MiClase objeto = new MiClase();

Ahi tenemos un método constructor no es asi ??... bueno, la sobrecarga consiste en realizar el mismo método pero con atributos totalmente distintos...


Código: (java) You are not allowed to view links. Register or Login
public class MiClase
{
    MiClase()
   {
      ....
   }
   MiClase(int a, int b)
   {
      ....
   }
}

De esta forma es totalmente válido realizar

Código: (java) You are not allowed to view links. Register or Login
MiClase objeto = new MiClase();
MiClase objeto = new MiClase(29,30);

La diferencia parte en la entrega de parámetros

Se entiende ??... Espero que si... :P, esta parte de la programación es bastante fácil de entender asi que no veo la complicación del pequeño ejemplo...

Ahora un ejemplo real:

Código: (java) You are not allowed to view links. Register or Login
pulic class MiClase
{
   private int a, b;

   MiClase(int x, int y)
   {
      a = x;
      b = y;
   }

   public int suma()
   {
      return (a + b);
   }
   public int suma (double a, double b)
   {
      return (a + b);
   }

   public void main(String [] args) throws IOException
   {

      MiClase obj = new MiClase(10 , 5);

      System.out.print ("La suma de los números es: " + obj.suma() + obj.suma(10, 2) );
   }
}

Espero haya quedado bastante claro... :D

El uso mas comun es la sobrecarga de constructores, dado que podemos tener de entrada todos los datos que nesesita la clase a la hora de inicializarla y entonces llamamos al constructor con varios parametros, o bien, no podemos saber nada de la clase y nesesitamos crearla, asi que llamamos al constructor de pocos parametros. Como el constructor solo puede tener un unico nombre es nesesario usar esta tecnica.

Saludos
« Última modificación: Abril 19, 2012, 09:38:46 am por WaesWaes »
SOLO LOS QUE DEJAN DE INTENTAR, FRACASARÁN...

Si no fuera por C, existiría Obol, Pasal, ++, #...

WinJaNet, abre sus puertas, para todos los programadores e interesados en programación!!


Desconectado vVegeta

  • JavaManiaco!
  • Si te metes con CPH
    te metes conmigo
  • ****
  • Mensajes: 1791
  • Sexo: Masculino
  • I´m Unique!!... vVegeta...
    • Ver Perfil
Re: JAVA desde CERO
« Respuesta #16 en: ſeptiembre 04, 2008, 10:06:04 pm »
Herencia

Que es lo primero que se les viene a la mente cuando se habla de herencia ???...

Practicamente Herencia se suele recurrir cuando un hijo hereda de su padre alguna característica en especial... o casi todo...

En JAVA no es distinto... pero tendremos clases hijos que heredan de la clase padre...

Es importante decidor cuando hay que usar una herencia, la pregunta que se tienen que responder es: la clase hijo ES la clase padre?

Por ejemplo:

Un circulo es una figura? Si -> pueden usar herencia
Una provincia es un pais? No -> si bien estan relacionados no es una relacion de herencia

Vamos a lo practico, el ejemplo mas usado es el de los empleados, hacemos una clase empleado y luego una hija que sea, por ejemplo, Ejecutivo, un ejecutivo ES UN empleado pero a diferencia del ordinario este puede, digamos, despedir a un empleado por ejemplo.

Código: (java) You are not allowed to view links. Register or Login
public class Empleado {
    private String nombre;
    private int sueldo;

    public Empleado(String n, int s) {
        nombre = n;
        sueldo = s;
    }

public void trabajar() { ... }

public void tenerVacaciones() { ... }

public void cobrar() { ... }
}

(si no entienden algo como los private no importa por ahora, mas adelante los veremos)

Bueno los metodo imaginenselos.

Ahora si queremos hacer una clase para el ejecutivo, no vamos a programar todo eso devuelta y a agregar un metodo mas que sea para despedir a alguien, vamos a usar la herencia para ahorrar codigo.

extends

Código: (java) You are not allowed to view links. Register or Login
Tipo_clase nombre_clase extends clase_padre
Código: (java) You are not allowed to view links. Register or Login
public class Ejecutivo extends Empleado
Más claro que el agua... :P

Ahora un ejemplo practico

Código: (java) You are not allowed to view links. Register or Login
public class Ejecutivo extends Empleado {

        public Ejecutivo(String n, int s) {
    nombre = n; //fijense que estamos seteando variables
            sueldo = s; //que supuestamente no existen, pero que estan heredadas en relidad
}

public void despedir(Empleado e) {
...
}
}

Tienen que darse cuanta que un ejecutivo tiene ademas de ese metodo todos los de un empleado normal, y todas sus variables, veamos con el main.

Código: (java) You are not allowed to view links. Register or Login
public class Main {

public static void main(String [] args){
Empleado em = new Empleado("juan" , 200);
//lo hacemos trabajar algunos dias.
for(int i=0; i<4; i++){
em.trabajar();
}
em.cobrar(); //y que cobre.

Ejecutivo ej = new Ejecutivo("pedro", 1500);
ej.cobrar();//metodo heredado
ej.tenerVacaciones(); //metodo heredado
ej.despedir(em); //este es metodo propio de el

}
}

Con este simple ejemplo de Herencia creo que ha de quedar claro, el para que, el como y el cuando se utiliza...

Saludos
« Última modificación: Abril 19, 2012, 10:03:31 am por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re: Programación Orientada al Objeto con UML y JAVA (JSE)
« Respuesta #17 en: Febrero 26, 2010, 06:15:21 pm »
La palabra reservada static

Se da por sabido en este apartado que el lector esta minimamente familiarizado con el concepto de clase, objeto y método, como así también tiene una noción de como definir clases y crear objetos de las mismas.

Cuando programamos en Java creamos clases que describen el comportamiento de los objetos que la instancien. Por tanto, el verdadero programa no existe sino hasta que se ejecuta el operador new que es el encargado de crear un objeto de alguna clase y reservar espacio en memoria para el mismo.

Ahora surge un problema trivial: ¿como usamos el operador new si aun no comenzó el programa, osea, no tenemos objetos en memoria que ejecuten dicho operador?

En un caso como el anterior, o por ejemplo si se quiere que un dato este permanentemente disponible sin importar el numero de objetos, o de la misma forma con los métodos, poder llamar a un método sin importar el numero de objetos.

Si han corrido un programa en Java o visto uno sabrán que a la definición del método main se le antepone la palabra reservada static,  esto es porque la palabra static hace que el método o dato no este relacionado con ninguna instancia en particular, de esta forma n es necesario crear objetos para llamar a métodos estáticos o trabajar con variables estáticas, por eso el método maines estático, porque lógicamente al llamarlo no hay ningún objeto en la memoria.

Así como los para acceder a datos y métodos no estáticos se deben de crear objetos primero, para los métodos y datos estáticos pasa lo mismo, si desde un método estático queremos llamar a uno no estático primero debemos crear un objeto. Es imposible acceder a un método o dato no estático sin instanciar una clase, ya que esos métodos y valores describen un objeto.

Para que un método a dato sea estático simplemente hay que anteponer la palabra reservada static en la definición:

Código: (java) You are not allowed to view links. Register or Login
class Prueba {
    //definicion de variables
    static int numero=10;
    .....
    //definicion de metodos
    .....
}

Para referirse a la variable numero de la clase Prueba se  nombra primero la clase en que se encuentra y luego el nombre de la variable:

Código: (java) You are not allowed to view links. Register or Login
Prueba.numero+=10;
Con lo que conseguimos aumentar en 10 el valor de la variable.

Esta es la forma normal de referirse a una variable estática, pero también se pueden llamar desde objetos:

Código: (java) You are not allowed to view links. Register or Login
Prueba P1 = new Prueba();
Prueba P2 = new Prueba();

Y la usamos de esta manera:

Código: (java) You are not allowed to view links. Register or Login
P1.numero+=10;
P2.numero+=10;

Aquí esta la diferencia de las variables estáticas, cuando definimos una variable no estática se supone que P1.numero es la variable numero que pertenece al objeto P1 y tiene un lugar en memoria exclusivo para ella y nadie mas, como asi el objeto P2 tiene otra variable, distinta pero con el mismo nombre en otro lugar de memoria y totalmente independiente.

En el caso de las variables estáticas por mas que creemos 1000 objetos la variable siempre es la misma ya que como se dijo, no esta asociada a ninguna instancia, de esta forma:

P1.numero == P2.numero

Pero no igual en valor, (si tienen el mismo valor pero también) son las mismas, es una sola variable llamada numero que se encuentra en un solo espacio de memoria, y podemos aceder a ella desde cualquier objeto o sin hacer uso de estos (si  los especificadores de acceso lo permiten), por lo tanto cuando hicimos esto:

Código: (java) You are not allowed to view links. Register or Login
P1.numero+=10;
P2.numero+=10;

No sumamos 10 a la variable de un objeto y 10 a la variable de otro objeto, sino que sumamos 10 a la variable estática numero desde un objeto, y luego desde otro objeto volvimos a sumarle 10, así que le sumamos 20 en total.

Por eso con frecuencia un método o variable estática son llamados método de clase o dato de clase, por el hecho de que clase hay una sola y todos los objetos que la hayan instanciado se comportan como la clase diga, y si el valor estático de una clase cambia, el valor ese cambia en todos los objetos, porque se encuentra en un solo lugar de memoria.

Como ya nombre esto es útil siempre y cuando queramos que un valor este siempre disponible sin impostar los objetos que existan, o que un valor se fijo para todos los objetos por mas que se cambie desde uno solo, o sino para poder llamar a un método sin necesidad de crear objetos

saludos.-
« Última modificación: Abril 05, 2012, 03:03:00 pm por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re: Programación Orientada al Objeto con UML y JAVA (JSE)
« Respuesta #18 en: Febrero 27, 2010, 01:00:45 am »
Sobreescritura

Dado por hecho que el usuario tiene conocimientos basicos sobre herencia y sobrecarga, procedo a explicar que es la sobreescritura.

Al igual que la sobrecarga este es un tema muy facil de entender, cuando se tiene una clase, lamemosla A que sera una superclase, y y tiene un clase B que sera una subclase.

Código: (java) You are not allowed to view links. Register or Login
public class A{
    ...
}

class B extends A {
   ...
}

En este caso todos los miembros de la clase A seran tambien miembros de la subclase B cierto??

Ahora supongamos que la clase A implementa de forma correcta un metodo que sirve para solucionar un determinado problema en dicha clase, ahora bien, cuando la clase B hereda este metodo resultara que en este nuevo entorno el metodo no es capaz de poder resolver el problema en su totalidad, sin embargo es necesario extender las clases por algun motivo en particular.

Bien para ese problema debemos hacer uso de la sobreescritura, que consiste en reescribir un metodo (o variable) para que funcione de manera correcta con los objetos de la clase B

Para reescribir un metodo debemos de: nombrar al metodo con el mismo nombre que el de la superclase, el mismo retorno y, a diferencia de la sobrecarga, debemos tambien pasarle la misma lista de argumentos, lo unico que cambia es el cuerpo del metodo en donde se reescribira el codigo para que funcione acorde a lo deseado.

Pongamos un ejemplo:

Código: (java) You are not allowed to view links. Register or Login
public class A {
    public void estoyEn() {
        System.out.println("Estoy en la clase A");
    }

    public int resta(int a, int b) {
        return (a-b);
    }
}

class B extends A {
    public void estoyEn() {
        System.out.println("Estoy en la clase B");
    }

    public int resta(int a, int b) {
        return(b-a);
    }
}

Como ven, en la clase B el metodo estoyEn() no servia, ya que hiba a decir que estaba en la clase A, asi que lo sobreescribimos para que se adecue a nuestras ambiciones  :) al igual que el de resta que en la clase B por algun motivo, necesitabamos que se reste al reves que en la clase A.

Entre los diversos usos que tiene esto, el mas comun es el de manipular librerias a nuestro gusto, por ejemplo, supongamos que hay una clase llamado JButton que se encarga de crear un boton, pero esa clase tiene un problema, el que la programo, hizo que los botones que genera sean rectangulares, y para nuestro programa necesitamos botones rendondos, en ese caso deberiamos crear una nueva clase llamada Boton por ejemplo, que herede la clase JButton, buscar el metodo en la clase JButton que hace que los botones sean rectangulares, sobreescribirlo en la clase Boton y hacer que los botones sean redondos (eso dependera de su destreza en la programacion :P )

Un ejemplo que va obligado a la sobreescritura es la la utilizacion de hilos el metodo para hacerlos correr, la clase Thread es la encargade de la gestion de hilos en Java, el metodo run() se encarga de empezar a hacer correr un hilo, pero en la clase Thread este metodo esta vacio...WTF?, asi es, porque es exclusivamente para sobreescribirlo. Si no entendieron lo que hable sobre hilos y demas no importa, fue a modo de ejemplo.

Los metodos estaticos no pueden ser sobreescritos, ya que como sabemos hay solo uno, que es estatico en el verdadero sentido de la palabra, metodos declarados como final tampoco, por si no saben, la palabra reservada final indica que el metodo o valor siempre va a ser constante, por ejemplo se utiliza, valga la redundancia, para definir constantes:

Código: (java) You are not allowed to view links. Register or Login
final int pi=3.1415926
Esa variable no podra cambiar en toda su vida, por eso mismo no se puede sobreescribir, tampoco es posible sobreescribir aquellos metodos los cuales su modificador de acceso nos lo prohiben, en cuanto a excepciones(throw) solo se pueden reducir o eliminar, pero no agregar o ampliar la existente.

saludos.-
« Última modificación: Abril 05, 2012, 03:03:44 pm por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re: Programación Orientada al Objeto con UML y JAVA (JSE)
« Respuesta #19 en: Marzo 16, 2010, 06:15:40 pm »
Polimorfismo

El polimorfismo es una caracteristica mas de la OOP que como toda caracteristica de este paradigrama sirve para separar el que del como ;)

No se muy bien como definirlo asi que voy a ir por partes:

Primero, el polimorfismo es una tecnica que se basa en la herencia.

Segundo: de cierta manera el polimorfismo trata sobre "desacoplar" tipos, esto es, definimos algo, pero no le damos un tipo.

Porque tendriamos que llegar a esta instancia de no definir un tipo??

porque sencillamente no sabemos que tipo se va a usar.....asi que se define un tipo abstracto(o no) y ese es el que
vale.

Como se que no se entendio aca les va un ejemplo...

supongamos que tenemos que crear un programa que se encarge de todos los nacimientos de las personas del mundo, esto es, cuando llamamos a la clase mujer el porgrama nos crea un objeto mujer que las variables le daran sus atributos y los metodos su comportamiento y de misma manera para el hombre, como ya saben a los objetos los diferenciamos entre si con el identificador, en este caso con el nombre de la persona....

Pero en este caso en particular tenemos dos objetos bastante similares, el hombre y la mujer, por lo tanto las similitudes entre ellos las definiremos en una clase "Persona" y las diferencias en una clase Hombre y Mujer respectivamente, cuyas clases seran hijas de la clase Persona cierto.
Código: (java) You are not allowed to view links. Register or Login
class Persona {
    //caracteristicas propias de las personas en general
}

class Mujer extends Persona {
    //caracteristicas propias de las mujeres en general 
}

class Hombre extends Persona {
   //caractereisticas propias de los hombres en general
}

Listo todo hecho para que nuestro programa empieze a crear personas ;)

pero....como definimos los objetos????

Código: (java) You are not allowed to view links. Register or Login
Hombre persona1 = new Hombre(altura,....);
Mujer persona2 = new Mujer(altura,....);

si, eso seria en el caso de que supiera el programador como vienen las persona...pero este programa le dara la libertad a la cigeaña de decidir en tiempo de ejecucion si quiere un hombre o una mujer....

Asi que la forma de programarlo seria haciendo uso del polimorfismo....asi

Código: (java) You are not allowed to view links. Register or Login
Persona persona1;
Y cuando la ciguaña haga click sobre mujer hacemos un

Código: (java) You are not allowed to view links. Register or Login
persona1 = new Mujer(altura,...);
Osea, seria un:

Código: (java) You are not allowed to view links. Register or Login
Persona persona1= new Mujer(altura,...);
Impresionante no?? un objeto Persona es igual a un objeto Mujer!!

Esto sirve siempre y cuando digamos que un tipo de objetyo padre es igual a un hijo....

Por lo tanto, los objetos polimorficoa habren una nueva frontera el la OOP porque hasta ahora diferenciabamos un objeto unicamente por su identificador:

Código: (java) You are not allowed to view links. Register or Login
Persona p1,p2;
son solo diferenciables por su identificador, p1 y p2. pero si p1 y p2 son objetos polimorficos puede que p1 comparta metodos que p2 ni siquiera conosca.

Esto es bastante util en varios casos que el usuario decida que clase de objetos quiere crear ya que el programador no se puede anticipar....por ejemplo si hacemos un paint con clases triangulo, cuadrado, circulo, etc, definimos una clase geometria que tenga metodos que todos comparten y despues hacemos las clases hijas extendiendolas de la clase Geometria y con sus metodos propios...a la hora de pedirle la figura al usuario como no sbemos que va a querer hacer definimos un objeto Geometria y despues le podemos hacer por ejemplo un:

Código: (java) You are not allowed to view links. Register or Login
Geometria figura1 = new Circulo(centro, radio);
o lo que queramos...

Bien eso es el polimorfismo....

pero...que pasa si la cigueña hace un:
Código: (java) You are not allowed to view links. Register or Login
Persona p1 = new Persona();
???

Maldita cigueña hacker, encontro un bug en nuestro programa xD

Una persona no existe en nuestro programa, porque no es hombre ni mujer, y no existe...

perosona es una abstraccion de hombres y mujeres humanos, como asi tambien hombres es una abstraccion de juan,pedro e ignacio verdad?? no existe "hombre" existen varios hombre distintos.

Aca es donde la OOP toma tambien cartas en el asunto y da la posibilidad de definir clases abstractas...tema que veremos en la proxima entrega ;)

saludos
« Última modificación: Abril 05, 2012, 03:04:09 pm por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re: Programación Orientada al Objeto con UML y JAVA (JSE)
« Respuesta #20 en: Mayo 01, 2010, 05:55:03 pm »
Abstrayendo la implementacion

En la programacion en general, la abstraccion es uno de los conceptos mas importantes, esto surge por la nesesidad de aislar problemas que no tienen que ver con la solucion en si, por ejemplos los primeros lenguajes de programacion intentaban abstraerse de las sentencias del procesador y llevar la programacion a un aspecto mas humano, eso comenzo con la programacion lineal y evoluciono a la programacion estructurada que es la que tanto se uso y se usa.

En la programacion orientada  a objetos se dio un paso mas que estos paradigmas y se insistio aun mas con el concepto de abstraccion.

La idea general es la abstraccion mediante objetos, para poder llegar a entender un problema (cuan grande sea) sin necesidad de entrar en detalles que no sirven para la solucion en si.

En software de gran calibre vale mucho mas el diseño del mismo que la programacion en si, la programacion, es solo un paso mas del desarrollo de software.

El diseño tiene que ser lo mas solido y abstracto posible, esto significa que se definan interfaces que declaren los metodos y datos que se deben de usar parar solucionar el problema, pero que no lo solucione en si.

La solucion viene a la hora de la implementacion, pero eso ahora carece de importancia porque no importa como resolver pequeños subproblemas sino el problema en general, veamos un ejemplo para aclarar el asunto, supongamos que tenemos que desarrollar un software que sera usado en un androide con la intencion de imitar a una persona normal =D

Habria que tener en mente varias cosas como levantarse, bañarse, vestirse, desayunar, trabajar, relacionarse socialmente, acostarse y todas cosas por el estilo, pero si empezaramos a programar la solucion entera de una, mientras estamos en un pequeño detalle de, por ejemplo el trabajo, podemos olvidar cosas importantes, como relacionarse socialmente en el trabajo....por eso lo que importa en primer momento es la idea general y hacer todo de una sin importar que es lo que se haga despues:

Código: (java) You are not allowed to view links. Register or Login
public interface Persona {
    public void levantarse();
    public void bañarse();
    public void vestirse();
    public void desayunar();
    public void trabajar();
    //....
}

Los metodos deben de ser neceseriamente abstractos porque en la interface no se implementa ninguno, la implementacion se define luego en las clases no abstractas.

Otra ventaja de hacer este tipo de abstraccion es que si cada persona que use el software quiere adaptarlo a sus necesidades las clases cambiaran porque ahi es donde se definen los detalles, pero si conseguimos diseñar un TDA solido el software en general no varia en lo mas minimo.

A la hora de la implementacion si nos ponemos mas quisquillosos y hacemos los detalles

Código: (java) You are not allowed to view links. Register or Login
class AndroideJuanPerez implements Persona {
    public void levantarse(){
        abrirLosOjos();
        destaparse();
        pararse();
        ...
    }
    public void bañarse(){...}
    public void vestirse(){
         agarrarEsmoquin();
         ...
    }
    public void desayunar(){...}
    public void trabajar(){...}
    ....
}

Como pueden ver Juan Perez quiere que su androide vista de esmoquin, pero el mismo programa se adapta facilmente a las necesidade de roberto, que uiere vestir de remera....

Código: (java) You are not allowed to view links. Register or Login
class AndroideRoberto implements Persona {
    public void levantarse(){
        abrirLosOjos();
        destaparse();
        pararse();
        ...
    }
    public void bañarse(){...}
    public void vestirse(){
         agarrarRemera();
         ...
    }
    public void desayunar(){...}
    public void trabajar(){...}
    ....
}

De esa forma podemos definir muchisimas implementaciones pero la estructura general del programa no varia, que en ciertos softwares es muy necesario que esto ocurra, como nota, decirles que si implementan una interface estan obligados a implementar todos sus metodos por mas que los definan vacios, esto es para asegurarse los diseñadores del software que el programa estara estructurado correctamente a pesar de la abstraccion.

Sobre el tema de interfaces se puede hablar mucho pero sirve de poco, lo mejor es que busquen informacion que hay en los libros y en internet en general que es suficiente, y vean codigo que haga uso de interfases para entender el verdadero funcionamiento de la abstraccion.

Con respecto a las clases abstractas no presentan gran diferencia con las interfaces, son clases donde no se puden instanciar objetos (osea llamar al constructor con el operador new) pero si permite definir datos y metodos para luego poder ser usado como objetos en clases de implementacion.

Un uso muy importante para las interfaces es la simulacion de herencia multiple en Java, como ya saben, les recuerdo simplemente, Java permite Herencia simple, esto es, que permite solo que una clase tenga un solo padre:
Código: (java) You are not allowed to view links. Register or Login
class Perro extends Animal {}
Pero en variadas ocaciones necesitamos que una clase tenga mas de un padre.

Por ejemplo si tenemos una clase que se relaciona con una marca (llamemosla A) de discos duros y tenemos otra clase que se relaciona con otra marca llamada B, resulta evidente pensar que cada clase sera hija de una clase llamada disco duros, ya que la diferencia entra marcas no sera demaciada y puede abstraerse...

Ahora supongamos que alguien usa un disco duro de la marca A en su computadora, simplemente la extendemos de la clase de la marca A y listo.

Pero si alguien hace un RAID usando un disco de cada marca deberiamos extender la clase PC de las dos marcas y no se puede!!!

Java contempla estos detalles y permite la herencia multiple a traves de las interfaces, no podemos extender mas de una clase, pero podemos implementar todas las interfaces que nos venga en gana =D

Las interfaces permiten ser extendidas, entonces la simulacion de la herencia multiple vendra por el lado de una interfas que juega un papel de "portadora de clases"...

Recomiendo que se lean esto para entender bien como funciona esta simulacion:

You are not allowed to view links. Register or Login

Porque Java no soporta la herencia multiple??

Bueno Java es un lenguaje que esta pensado para ser seguro y legible, algunos pueden pensar que dejar de lado cosas como punteros, estructuras, destructures, o incluso herencia multiple, le juegan en contra...pero los desarrolladores de Java no los dejaron de lado, no por ora cosa que por conveniencia.

La herencia multiple es ambigua y agrega a un programa cierto grado de complejidad que es casi siempre innecesaria, por ejemplo pueden leer sobre el You are not allowed to view links. Register or Login

Quizas agrande mas esta seccion, pero recuerden que la unica manera de aprender a programar bien es: "leer mucho codigo, escribir mucho codigo".

Diferencias entre una clase abstracta y una interface

En Java existen dos palabras reservadas: abstract y interface

abstract es aplicado a una clase de esta forma:

Código: (java) You are not allowed to view links. Register or Login
public abstract class MiClase {
}

Que es lo que cambia que sea una clase abstract?, basicamente podemos dejar algunos metodos sin implementar, porque probablemente no sabemos como hacerlo a estas alturas en el sentido que se esta en un nivel muy ganeral, por ejemplo seria algo asi:

Código: (java) You are not allowed to view links. Register or Login
public abstract class MiClase {
    public void mostrar(){
        System.out,println("Hola");
    }

    abstract void cambiar();
}

Como pueden ver "cambiar()" no tiene cuerpo es decir que no tiene un comportamiento definido.

Que es lo que se pierde con esto? bueno, basicamente no podemos instanciar la clase, y es obvio porque si la pudieramos instanciar y llamamos al metodo cambiar() explota todo xD

Sirve entonces si algun hijo de esa clase no es abstract e implementa dicho metodo, de esa forma podemos instanciar al hijo y ahi si usarlo.

La principal caracteristica de estas clases es la reutilizacion de codigo, veamos un ejemplo de figuras:

Código: (java) You are not allowed to view links. Register or Login
abstract class Figura {
private String nombre;

public Figura(String n) {
nombre = n;
}

public String getNombre() {
return nombre;
}

public abstract double getArea(); 

}

class Circulo extends Figura{

private int radio;

public Circulo(String n, int r) {
super(n);
radio = r;
}

public double getArea() {
return 3.14 * radio * radio;
}

}

class Rectangulo extends Figura{

private int lado1, lado2;

public Rectangulo(String n, int l1, int l2) {
super(n);
lado1 = l1;
lado2 = l2;
}

public double getArea() {
return lado1 * lado2;
}
}

public class Main {
public static void main(String[] args){
Figura a = new Circulo("carlos", 3);
Figura b = new Rectangulo("pepe", 4, 5);

System.out.println(a.getNombre());
System.out.println(b.getNombre());

System.out.println(a.getArea());
System.out.println(b.getArea());
}
}

En este codigo aparece la palabra *super* que se explica un poco mas adelante, a fines practicos es llamar al constructor del padre.

Como pueden ver el codigo es simple, se manejan dos figuras, un circulo y un rectangulo. Se les asigna un nombre y una dimension, el nombre es similar para los dos, pero las dimensiones son diferentes porque las figuras son distintas.

Si el comportamiento del manejo de nombres es el mismo, esta MAL en lo que es programacion orientada a objetos, escribirlo dos veces igual en cada clase, por eso se hace un padre que es Figura que el manejo de nombre lo hace ella pero no es capaz de poder defir el metodo getArea(), porque obvio este varia segun sea la figura, entonces los hijos implementan ese metodo pero no hace falta lo del nombre porque ya se soluciono en un nivel de abstraccion mas arriba.

Luego como ven desde el main, se crean dos objetos y se llaman a los dos metodos del nombre, los cuales son los mismo, los del padre, y luego se llaman a los de area que ahi si es el de esa clase en particular.

Interfaces

Las interfaces son similares a las clase abstractas pero tienen unas diferencias que las hacen especiales.

1. Todos los metodos no tiene implementacion
2. Todos los metodos son public (por mas que no los definamos asi).

Como no definen nada no son muy utiles pero sirven como un protocolo entre clases que especifica como debe llamarse los metodos y de que tipo deben ser, ademas las interfaces nos obligan a implementar todos sus metodos (porque sino no podriamos instanciar) asi que esta bueno para usarlas (es obvio lo que digo) como interfaces :freak:

El uso mas comun es el de herencia multiple, como no tiene implementacion no sucede nada si extiendo de mas de una, a diferencia de las clases abstractas que por ejemplo en el problema del diamante hay una duplicacion de codigo media implicita o por ejemplo si las dos padres tienen un metodo igual en cuanto a nombre tipo y parametros pero con comportamiento distinto en el hijo eso es un desastre.

para usar una interface se hace:

Código: (java) You are not allowed to view links. Register or Login
class MiClase implements Interfaz1
y se puede usar junto con una herencia normal:

Código: (java) You are not allowed to view links. Register or Login
class MiClase extends Padre implements Interfaz1
Y mas de una:

Código: (java) You are not allowed to view links. Register or Login
class MiClase extends Padre implements Interfaz1, Interfaz2, Interfaz3
Aca tambien existe la colision de nombres entre metodos, pero no es de implementacion, hay un rejunte de sobrecarga y sobreescritura juntas que es feo para el ojo, asi que vas a tener que hacer lo posible para que no te pase ;)

Ya se vio como se manejan las interfaces, vamos a ver un ejemplo medio ilustrativo:

Código: (java) You are not allowed to view links. Register or Login
class Docente {

private String tareaDocente = "Enseniar";

public String getTareaDocente() {
return tareaDocente;
}

}

interface iAlumno {
String tareaAlumno = "Aprender";
String getTareaAlumno();
}

class Alumno implements iAlumno {

public String getTareaAlumno() {
return tareaAlumno;
}

}

class AyudanteDeCatedra extends Docente implements iAlumno {
//obligado a hacer esto, sino no compila (adentro puede ir lo que quieran)
public String getTareaAlumno(){
return null;
}

public String getTareaAyudante() {
return getTareaDocente() + " y " + tareaAlumno;
}
}



public class Main {
public static void main(String[] args){
Docente d = new Docente();
Alumno a = new Alumno();
AyudanteDeCatedra ac = new AyudanteDeCatedra();

System.out.println(d.getTareaDocente());
System.out.println(a.getTareaAlumno());
System.out.println(ac.getTareaAyudante());
}
}

La onda es que hay docentes que enseñan, alumnos que aprenden y alumnos que tiene que aprender pero fueron elegudos como ayudantes asi que tambien tiene que enseñar.

El ejemplo tiene algunos problemas, ya que entre docente y alumno se puede abstraer algo de implementacion pero no lo vamos hacer para que se entienda el ejemplo.

La onda es que que se crea un docente y se pide que tareas es la que hace.

Despues para alumno hay un interface que define sus atributos y comportamiento, se crea uno y se pide su tarea, tampoco me parece que sea complicado

Para ayudante se ve que heredamos Docente asi que podemos hacer uso del metodo que tiene definido.

En cuanto a la interfaz como todo es publico, tenemos acceso a todo (incluso la variable) asi que la usamos directamente, y algo importante es que estamos obligados a implementar el metodo ese, asi lo hagamos vacio (perdon pero no se me ocurrio un buen ejemplo xD)

Espero que mas o menos se pueda llegar a entender. Esto es casi la base de POO junto con el tema de objetos, herencia y polimorfismo, asi que les recomiendo leer algun libro sobre esto, pueden ver: Thinking in java, que esta bueno y tienen version en español.

Saludos


« Última modificación: Abril 15, 2012, 09:59:28 am por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #21 en: Abril 05, 2012, 01:47:59 pm »
Modificadores de Acceso

Este es un capitulo simple, pero sirve para explicar porque poner o no poner una palabra delante de cada declaracion que se hace.

Ya se habran encontrado con palabras como:

Código: (java) You are not allowed to view links. Register or Login
public
private
protected

Son los llamados modificadores de acceso y hay cuatro (ademas de esos tres esta package que se logra no escribiendo nada).

Sirven para indicar desde que lugares se puede acceder a ese metodo o variable y desde que lugares no. Este cuadro explica bien como funcionan.


Por ejemplo se tiene el hola mundo ordinario:

Código: (java) You are not allowed to view links. Register or Login
public class Hola {
    public void hola(){
        System.out.println("Hola mundo");
    }
}

Se pueden ver 2 public, el de la clase indica que esa clase en publica y se puede ver desde cualquier otro lugar, y el metodo hola tambien es publico asi que desde cualquier otra clase en cualquier lugar se puede hacer algo del estilo

Código: (java) You are not allowed to view links. Register or Login
Hola h = new Hola();
h.hola();

Lo que mostrara "hola" por pantalla.

Esto no siempre es deseado, sobretodo en proyecto de mayor embergadura puede ser que nesesitemos que algunos metodos o variables no puedan ser modificadas ni accedidas desde clases que estan en otra carpeta, para eso quitamos el public y ya esta:

Código: (java) You are not allowed to view links. Register or Login
public class Hola {
    void hola(){
        System.out.println("Hola mundo");
    }
}

Si se ejecuta:

Código: (java) You are not allowed to view links. Register or Login
Hola h = new Hola();
h.hola();

En una clase que no esta en la misma carpeta sera un error de compilacion.

Uno de los mas usados es private, quiere decir que nadie lo puede tocar a excepcion de la misma clase:

Código: (java) You are not allowed to view links. Register or Login
public class Hola {
    private void hola(){
        System.out.println("Hola mundo");
    }
}

El codigo:

Código: (java) You are not allowed to view links. Register or Login
Hola h = new Hola();
h.hola();

Desde cualquier clase que no sea esa misma dara un error. private es muy usado en las variable, normalmente en Java y la programacion orientada a objetos se usan metodos setters y getters para obtener y setear las variables de una clase, porque si cambia el tipo de variable solo hay que cambiar esos metodos y no todos los que tocan las variables en todo el codigo, para esto es necesaria que las variables sean private, para obligar a usar esos metodos si o si.

El ultimo es protected, que solo sirve en casos de herencia, quiere decir que esa clase podra y sus hijas tambien.

Código: (java) You are not allowed to view links. Register or Login
public class Hola {
    protected void hola(){
        System.out.println("Hola mundo");
    }
}

Recuerden que se puede poner un modificador de acceso a un metodo, variable, clase, interfaz, etc.

Saludos

 
« Última modificación: Abril 19, 2012, 09:23:01 am por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #22 en: Abril 05, 2012, 01:52:38 pm »
Explicacion del main

Un capitulo corto y sin sentido pero que sirve para despejar las dudas que por ahi nunca se preguntaron...el main :

Código: (java) You are not allowed to view links. Register or Login
public static void main(String[] args)

Porque hay que escribir todo eso, y que significa?

A estas alturas del post ya tendrian que deducirlo pero vamos a verlo:

Código: (java) You are not allowed to view links. Register or Login
public
Indica que se puede utilizar ese metodo desde cualquier lugar, esto es necesario porque queremos que nuestro programa se pueda ejecutar desde cualquier lado.

Código: (java) You are not allowed to view links. Register or Login
static
Si no ponemos esto estamos diciendo que solo podremos usar el main si instanciamos la clase, pero, quien la va a instanciar si el programa todavia no esta corriendo, es sumamente necesario que el main sea static, porque es ese momento no hay quien instancie.

Código: (java) You are not allowed to view links. Register or Login
void
Una ves terminado el programa no se requiere ningun valor de retorno (a diferencia con lenguajes como C que retornaban un int indicando que habia sucedido con la ejecucion del programa)

Código: (java) You are not allowed to view links. Register or Login
main
Es el nombre reservado para este metodo particular

Código: (java) You are not allowed to view links. Register or Login
String[] args
Es una lista de parametros que se puede utilizar opcionalmente, la razon por la que no es necesario incluir: "java.lang.String" para utilizar Strings

Indica un arreglo unidireccional de Strings que se llama "args" (se puede poner cualquier nombre, "args" y "arg" se usan comvencionalmente pero cualquiera vale) si ejecutas tu programa desde un IDE no vas a poder ver esta foncionalidad pero si usas la consola si.

Código: (java) You are not allowed to view links. Register or Login
public class programa {
  public static void main ( String[] args ) {
    System.out.println( "Hay " + args.length + " argumentos" );
    for ( int i = 0; i < args.length; i++ ) {
      System.out.println( args[i] );
    }
  }
}

Si ejecutas desde el IDE o desde consola asi:

Código: You are not allowed to view links. Register or Login
java programa
Vas a obtener: "Hay 0 argumentos"

Pero si se ejecuta desde consola asi:

Código: You are not allowed to view links. Register or Login
java programa hola como estas
vas a obtener:

Hay 0 argumentos
hola
como
estas

Como se puede ver todo lo que sigue despues del nombre del programa se toma como un un arreglo de Strings que esta dividido por los espacios en blanco, esto es util para agilizar el programa o a la hora de automatizar el mismo.

Eso es todo, recuerden que como es una definicion de arreglo tambien pueden hacer:

Código: (java) You are not allowed to view links. Register or Login
String args[]
Osea cambiar el orden del nombre con los corchetes.

Otro tema totalmente aparte que quiero dejar aclarado es:

Aclaracion: Basicamente hay tres formas en las que se puede arrancar un programa, la primera y la menos deseable ya que no respeta lo de la programacion orientada a objetos es programar en el main de esta forma.

Código: (java) You are not allowed to view links. Register or Login
public class Hola{
   public static void main(String[] args){
       int a = 3;
       System.out.println( "Hola como estas?");
   }
}

Aunque en programas chicos se puede usar y no queda mal, la segunda es mucho mejor y consiste en crear un objeto en el main y que ese objeto se encargue de la ejecucion del programa (digo mejor porque estamos esquivando a static que choca contra el paradigma).


Código: (java) You are not allowed to view links. Register or Login
public class Hola{
   
   public Hola(){
       int a = 3;
       System.out.println( "Hola como estas?");
   }

   public static void main(String[] args){
      Hola h = new Hola();
   }
}

Y la tercera que es aun mas prolija es dejar el main en una clase sola, para asi separar lo static de lo demas:

Código: (java) You are not allowed to view links. Register or Login
public class Hola{
   public Hola(){
       int a = 3;
       System.out.println( "Hola como estas?");
   }
}


Código: (java) You are not allowed to view links. Register or Login
public class Main{
   public static void main(String[] args){
      Hola h = new Hola();
   }
}

Esos dos archivos tiene que estar en el mismo directorio...

De cualquier forma anda, pero son diferentes ;)
« Última modificación: Abril 05, 2012, 03:31:08 pm por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #23 en: Abril 05, 2012, 06:27:49 pm »
Palabra reservada this

this se usa para hacer una referencia explicita a un objeto. En el caso de que haya ambiguadades con los identificadores, o se use una forma de programar rara, se usa this. Lo mejor y mas usado es para resolver ambivalencias, por ejemplo:

Código: (java) You are not allowed to view links. Register or Login
class Suma {
    int a;
    public Suma(int a){
         a = a;
    }
}

Es claro lo que esta pasando, tenemos una variable "a" dentro de una clase, y queremos que cuando se cree un objeto de esa clase se le asigne un valor, por parametro el constructor recibe un int, al que tambien se lo llamo "a" entonces dentro del constructor existe 2 variables distintas con nombre "a", para esto se usa this. this indicara SU "a" es decir la de la clase.

Código: (java) You are not allowed to view links. Register or Login
class Suma {
    int a;
    public Suma(int a){
         this.a = a;
    }
}

Solucionado, otra solucion era la de cambiar el nombre de cualquiera de las dos variables, pero aveces con el tema de las herencias, se repiten nombres de metodos y variables y es necesario que este this.

Como les decia tambien se puede usar para programar algo medio loco...como dije al principio, this es una referencia al objeto, entonces cuando dije "this.a" dije la a de mi objeto, pero tambien se puede usar this por si solo, es decir el objeto.

Podemos entonces manejar el objeto en si, por ejemplo miren este codigo que lo saque de "Thinking in Java":

Código: (java) You are not allowed to view links. Register or Login
public class Hoja {
    int i=0;
    Hoja incremento() {
        i++;
        return this;
    }

    void print () {
        System.out.println("i = " + i);
    }

    public static void main(String[] args) {
        Hoja x = new Hoja();
        x.incremento().incremento().incremento().print();
    }
}

Hay una clase Hoja , desde el main se crea un objeto de la misma que se llama x, luego se hace "x.incremento()"

como ven "incremento()" devuelve algo, y no es un int o un char, devuelve un tipo "Hoja" osea un objeto del mismo tipo, y en el return se puso "this" entonces en realidad se esta devolviendo a si mismo.

Lo que hace es sumar una a la variable y devolver TODO el objeto, no la variable ...

Como se devuelve el objeto es posible acceder a toda su interfaz por eso es que se puede hacer: x.incremento().incremento().incremento()

Porque cada "incremento" es un objeto y se vuelve a usar, luego termina por usar el metodo print para mostar por pantalla un 3. y ya no es posible usar otro metodo porque print no devuelve un objeto.

Esto es solo como comentario para que vean otro posible uso.

Palabra reservada super


super hace referencia a la clase padre. Al igual que this hacia referencia a si mismo, super hace referencia al padre, por lo tanto solo se usa cuando hay herencia, y tambien es usada para eliminar ambivalencias, o para obtener una referencia del padre si se quiere pregramar algo loco =)

Vamos a ver el ejemplo basico y vamos a combinarlo con this tambien:

Código: (java) You are not allowed to view links. Register or Login
public class Main {
    public static void main(String[] args) {
        Hijo h = new Hijo(4);
    }
}


class Padre {
    int a = 2;
}

class Hijo extends Padre {
    int a = 0;
    public Hijo(int a) {
        System.out.println( a ); // 4 es el que entro por parametro
        System.out.println( this.a ); // 0 es el del objeto
        System.out.println( super.a ); // 2 es el del padre
    }
}

Con eso se tiene que haber entendido supongo.

En la herencia se usa para llamar al constructor del padre:

Código: (java) You are not allowed to view links. Register or Login
class Padre {
    public Padre() { ... }
}

clas Hijo extends Padre {
    public Hijo() {
        super();
    }
}

Algo importante es que SIEMPRE se llama al constructor del padre desde la clase hija, aunque no pongamos "super" explicitamente, por eso si el contructor del padre tiene argumentos tirara un error y tendremos que hacer el super a mano.

Otra caracteristica importante es que super siempre debe ser la primer linea del constructur del hijo, no nos deja que la pongamos como segunda o mas abajo aun.
Palabra reservada final

final no tiene nada que ver con las anteriores, el objetivo es hacer que algo no se pueda modificar durante la ejecucion del programa.

Variables final

Si definimos una variable primitiva (int, char, etc) como final, estamos dandole el comportamiento de una constante:

Código: (java) You are not allowed to view links. Register or Login
final double pi = 3.14;
Las variables finales normalmente se les asignan un valor en tiempo de compilacion, pero este valor no nesesariamente tiene que ser conocido, podemos igualarla a un valor random por ejemplo.

Objetos final

Tiene otros usos, aunque no se dan tan seguido en un ambiente real, por ejemplo si se define un manejador de objeto como final:

Código: (java) You are not allowed to view links. Register or Login
final Clase obj = new Clase()
En este caso el objeto si se puede modificar, supongamos que tiene un metodo "setNombre(String)" que le asigna un nombre, lo podriamos usar tranquilamente, lo que esta haciendo final es que no se pueda modificar el manejador del objeto, de esta forma es imposible hacer:

Código: (java) You are not allowed to view links. Register or Login
obj = new Clase()
No se puede, porque era final.

Tambien es posible declarar finales vacios, y darles diferentes valores a lo largo del codigo, dependiendo de que rama de codigo se ejecute, la variable tomara ese valor y despues no se podra modificar, aca hay que tener un poco de paciencia al compilador porque nos va a decir que en varios lado no se inicializa, pero se puede lograr, y la ventaja es que obtenemos una especie de variable que nosotros asignamos en tiempo de ejecucion pero que es inmutable.

Código: (java) You are not allowed to view links. Register or Login
class Hola {
    final int f;

    Hola() {
        f = 0;
        //...
    }

    Hola(int a) {
        f = a;
        //...
    }

    public static void main(String[] args) {
        Hola h = new Hola();
    }
}

De esa forma la variable final valdra 0, por ejemplo, fijense que siempre hay que inicializarla en algo.

Argumentos final

Otro uso muy importante es dentro de la lista de argumentos, supongan que tenemos un dato que manejamos sin ser final pero se lo damos a un metodo y queremos que no se modificado por ese metodo, eso es muy facil.

Código: (java) You are not allowed to view links. Register or Login
void mostrar(final String cadena){
    //...
}

De esta forma nos aseguramos que el metodo mostrar (que no tendria porque modificar el String) no lo modifique.

Metodos final.

Un metodo se hace final por dos razones, una es que dicho metodo tendra un mejor rendimiento, porque a los ojos del compilador al ser final puede traducirlo mejor a un nivel mas bajo y de esa forma ganamos rendimiento, la segunda y mas usada es para evitar la sobreescritura (ya todos saben no?) si una clase hija intenta modificar un metodo que siempre tiene que tener uncomportamiento igual, y ese metodo es final, ella no podra ;)

Un dato curioso es que los metodos private son implicitamente final, porque como nadie puede sobreescribirlos ni nada por el estilo, el compilador los declara final (que no agrega nada extra) y puede usar las ventajas de rendimiento que tiene hacer un metodo final.

Hay que tener mucho cuidado!! Por ahi te parece lindo declarar un metodo final porque nunca va a ser sobreescrito y te ganas un plus de rendimiento, pero nunca se sabe cuando un proyecto sera modificado y donde lo sera, asi, en un futuro puede que se nesesite sobrecargar ese metodo y se va a tener que tocar el codigo viejo lo cual no es la filosofia de POO, solo declaralo final cuando estes totalmente seguro de que va a ser final.

Clases final

Declara a toda una clase como final implica que dicha clase no podra ser heredada por nadie, tambien se hace por cuestiones de diseño pero aca tambien hay que tener cuidado con lo que se hace si algun dia intentamos modificar el software, tambien se tienen ganacias en redimiento si se hace algo de este estilo.


Saludos.
« Última modificación: Abril 20, 2012, 03:54:35 pm por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #24 en: Abril 06, 2012, 05:02:31 pm »
Operador cast

El operador cast es uno de los que no se mostro en la seccion de operadores ya que es algo complejo, sirve para pasar de un tipo de dato a otro siempre y cuando sea posible.

Para que sea posible pasar de un tipo de dato a otro sin perder presicion, el nuevo tipo tiene que ser mas abarcativo que el viejo, por ejemplo: si tenemos un int y lo pasamos a long, todo estara bien, pero si tenemos un int y lo pasamos a byte puede que todo quede bien o que perdamos algunos bits de relavancia que arruinan el valor.

De todas formas no quiere decir que no se pueda por mas que se pierda presicion.

Vamos a ver:

Código: (java) You are not allowed to view links. Register or Login
Tipo_de_dato nombre = ( Tipo_de_dato ) Valor
El operador es el que esta entre parentesis, por ejemplo:

Código: (java) You are not allowed to view links. Register or Login
int a = 10;
short b = (short) a;

Si por ejemplo pasamos de int a long el casting es implicito, como el tipo es mas grande no hace falta poner nada =D

Por ejemplo si hacemos

Código: (java) You are not allowed to view links. Register or Login
long a = 1000;
en realidad el 1000 esta en tipo int y se castea implicitamente, pero si queremos hacer:

Código: (java) You are not allowed to view links. Register or Login
byte a = 10;
El 10 es un int, por eso lo mas recomendable es hacer el cast explicito:

Código: (java) You are not allowed to view links. Register or Login
byte a = (byte) 10
Lo mismo pasa con los double y float, lo mejor es hacer:

Código: (java) You are not allowed to view links. Register or Login
float f = (float)3.14;
Para inicializar un long muy grande es parecido, si hacemos:

Código: (java) You are not allowed to view links. Register or Login
long a = 10000000000;
No va a compilar, porque el int esta exedido, sin embrago si hacemos el casting :

Código: (java) You are not allowed to view links. Register or Login
long a = (long)10000000000;
Tampoco sirve porque el int esta exedido antes de castear, para que ande hay que hacer asi:

Código: (java) You are not allowed to view links. Register or Login
long a = 10000000000L;
O

Código: (java) You are not allowed to view links. Register or Login
long a = 10000000000l;
Notar que hay una L (minuscula o mayuscula) al final que indica que es un long, de esa forma si interpreta asi de una y no se rompe nada =D

Otras cosas importantes es pasar de char a int y eso.

Si tenemos un int y lo hacemos char, lo que en realidad pasa no es que 2 se vuelve '2' sino que se vuelve el char numero 2 de la tabla ascii, asi:

Código: (java) You are not allowed to view links. Register or Login
int a = 65;
char b = (char) a;

b va a ser 'A' que es el caracter numero 65 en la tabla ascii.

Para obtener el int como char o al reves se usan unas clases que se veran a continuacion.

Las clases de los tipos de datos (Clases envoltorio)

Aunque Java es totalmete orientado a objetos todos sabemos que hay varias cosas que no son un objeto, como por ejemplo cualquier cosa definida como static y los tipos de datos (int = 1; no tiene en ningun lado un objeto).

La decision de hacer los tipos de datos primitivos sirve para hacerlo mas rapido, y mas comodo, sin embargo se pierde la esencia de la programacion orientada a objetos, que es guardar varios datos y metodos relacionados a algo en comun en un solo lugar.

Pero en Java tambien hicieron una clase para mantener esto vivo, por eso, cada tipo primitivo tiene una clase asosiada. Y se pueden usar varias variables y metodos muy utilies que con un tipo primitivo no se podia. (se encuentran en java.lang)

Vamos a ver por ejemplo la clase del tipo int, la clase Integer.

Ahora en ves de hacer:

Código: (java) You are not allowed to view links. Register or Login
int = 30;
Se hace a lo objetos asi:

Código: (java) You are not allowed to view links. Register or Login
Integer num = new Integer (30);
Y las ventajas?

Podemos acceder a dos variables que indican el valor maximo y minimo, a varios metodos entre los que se destacan parseInt() que permite pasar un String a int, y permite indicar la base (decimal, binario, etc). y pasar de Integer a String.

En cuanto a la clase Character tiene metodos que permiten saber si es mayuscula o no, si es digito o letra entre otros.

Como esto es medio informativo lo mejor es leer la API.

You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login

Saludos

« Última modificación: Abril 19, 2012, 09:22:16 am por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #25 en: Abril 08, 2012, 03:51:22 pm »
La clase Math

Siempre es importante saber como manejar algo de matematicas mas avanzadas de lo comun en cualquier lenguaje, para esto Java tiene la clase Math que esta en java.lang.Math

Esta clase es algo diferente a las demas, por empezar el constructor esta declarado como privado, por lo que no podemos generar instancias de ella, y todos sus metodos (o por lo menos los que sirven) son static, asi que es conocida como una clase utilitaria mas bien.

La clase brinda dos constantes bastantes utiles:

Código: (java) You are not allowed to view links. Register or Login
System.out.println("e: " + Math.E);
System.out.println("pi: " + Math.PI);

Luego tiene metodos para calcular:

Valor absoluto
Potencias
Raices
Cosenos, Senos, Tangentes (y los mismos pero hiperbolicos, y los arco)
Redondeo
Funcion piso y techo
Calcular el signo de un numeros
Calcular maximo y minimo entre numeros
Pasar de grados a radianes y viceversa
Generar numeros aleatorios
Calcular logaritmos y exponenciales
Retornar exponentes
Calcular distancia euclidia

En fin pueden ver la especificacion de la Api aca:

You are not allowed to view links. Register or Login.

Para los que les interese existe una clase que se llama StrictMath que es similar a Math, solo que StrictMath hace uso de librerias nativas en C, para optimizar mas las operaciones en punto flotante. Math hace uso de StrictMath asi que llamar a una y a otra es practicamente lo mismo, simplemente estan separadas porque en Math no hay codigo nativo y hay algunas cosas implemetadas que no estan en StrictMath, ademas Math antiguamente implementaba varias cosas en Java que ahora se delegan a la libreria fdlibm que esta en C.

Vamos a ver un ejemplo:

Código: (java) You are not allowed to view links. Register or Login
public class MathLibraryExample {

  public static void main(String[] args) {
   
    int i = 7;
    int j = -9;
    double x = 72.3;
    double y = 0.34;
 
    System.out.println("i is " + i);     
    System.out.println("j is " + j);
    System.out.println("x is " + x);     
    System.out.println("y is " + y);
     
    // The absolute value of a number is equal to
    // the number if the number is positive or
    // zero and equal to the negative of the number
    // if the number is negative.
 
    System.out.println("|" + i + "| is " + Math.abs(i));     
    System.out.println("|" + j + "| is " + Math.abs(j));
    System.out.println("|" + x + "| is " + Math.abs(x));     
    System.out.println("|" + y + "| is " + Math.abs(y));

    // Truncating and Rounding functions
 
    // You can round off a floating point number 
    // to the nearest integer with round()
     System.out.println(x + " is approximately " + Math.round(x));     
     System.out.println(y + " is approximately " + Math.round(y));     

    // The "ceiling" of a number is the   
    // smallest integer greater than or equal to
    // the number. Every integer is its own
    // ceiling.
     System.out.println("The ceiling of " + i + " is " + Math.ceil(i));     
     System.out.println("The ceiling of " + j + " is " + Math.ceil(j));
     System.out.println("The ceiling of " + x + " is " + Math.ceil(x));     
     System.out.println("The ceiling of " + y + " is " + Math.ceil(y));

     // The "floor" of a number is the largest 
     // integer less than or equal to the number.
     // Every integer is its own floor.
     System.out.println("The floor of " + i + " is " + Math.floor(i));     
     System.out.println("The floor of " + j + " is " + Math.floor(j));
     System.out.println("The floor of " + x + " is " + Math.floor(x));     
     System.out.println("The floor of " + y + " is " + Math.floor(y));

     // Comparison operators

     // min() returns the smaller of the two arguments you pass it
     System.out.println("min(" + i + "," + j + ") is " + Math.min(i,j));     
     System.out.println("min(" + x + "," + y + ") is " + Math.min(x,y));     
     System.out.println("min(" + i + "," + x + ") is " + Math.min(i,x));     
     System.out.println("min(" + y + "," + j + ") is " + Math.min(y,j));     

     // There's a corresponding max() method
     // that returns the larger of two numbers
     System.out.println("max(" + i + "," + j + ") is " + Math.max(i,j));     
     System.out.println("max(" + x + "," + y + ") is " + Math.max(x,y));     
     System.out.println("max(" + i + "," + x + ") is " + Math.max(i,x));     
     System.out.println("max(" + y + "," + j + ") is " + Math.max(y,j));     
     
     // The Math library defines a couple
     // of useful constants:
     System.out.println("Pi is " + Math.PI);     
     System.out.println("e is " + Math.E);       
     // Trigonometric methods
    // All arguments are given in radians
 
    // Convert a 45 degree angle to radians
    double angle = 45.0 * 2.0 * Math.PI/360.0;
    System.out.println("cos(" + angle + ") is " + Math.cos(angle));     
    System.out.println("sin(" + angle + ") is " + Math.sin(angle));     
   
     // Inverse Trigonometric methods
     // All values are returned as radians
   
    double value = 0.707;

    System.out.println("acos(" + value + ") is " + Math.acos(value));     
    System.out.println("asin(" + value + ") is " + Math.asin(value));     
    System.out.println("atan(" + value + ") is " + Math.atan(value));     

    // Exponential and Logarithmic Methods
 
    // exp(a) returns e (2.71828...) raised
    // to the power of a.   
    System.out.println("exp(1.0) is "  + Math.exp(1.0));
    System.out.println("exp(10.0) is " + Math.exp(10.0));
    System.out.println("exp(0.0) is "  +  Math.exp(0.0));

    // log(a) returns  the natural
    // logarithm (base e) of a.
    System.out.println("log(1.0) is "    + Math.log(1.0));
    System.out.println("log(10.0) is "   + Math.log(10.0));
    System.out.println("log(Math.E) is " + Math.log(Math.E));

    // pow(x, y) returns the x raised
    // to the yth power.
    System.out.println("pow(2.0, 2.0) is "  + Math.pow(2.0,2.0));
    System.out.println("pow(10.0, 3.5) is " + Math.pow(10.0,3.5));
    System.out.println("pow(8, -1) is "     + Math.pow(8,-1));

    // sqrt(x) returns the square root of x.
    for (i=0; i < 10; i++) {
      System.out.println(
       "The square root of " + i + " is " + Math.sqrt(i));
    }

       
    // Finally there's one Random method
    // that returns a pseudo-random number
    // between 0.0 and 1.0;
   
    System.out.println("Here's one random number: " + Math.random());     
    System.out.println("Here's another random number: " + Math.random());

  }

}

Que produce la salida:
Código: You are not allowed to view links. Register or Login
i is 7
j is -9
x is 72.3
y is 0.34
|7| is 7
|-9| is 9
|72.3| is 72.3
|0.34| is 0.34
72.3 is approximately 72
0.34 is approximately 0
The ceiling of 7 is 7
The ceiling of -9 is -9
The ceiling of 72.3 is 73
The ceiling of 0.34 is 1
The floor of 7 is 7
The floor of -9 is -9
The floor of 72.3 is 72
The floor of 0.34 is 0
min(7,-9) is -9
min(72.3,0.34) is 0.34
min(7,72.3) is 7
min(0.34,-9) is -9
max(7,-9) is 7
max(72.3,0.34) is 72.3
max(7,72.3) is 72.3
max(0.34,-9) is 0.34
Pi is 3.14159
e is 2.71828
cos(0.785398) is 0.707107
sin(0.785398) is 0.707107
acos(0.707) is 0.785549
asin(0.707) is 0.785247
atan(0.707) is 0.615409
exp(1.0) is 2.71828
exp(10.0) is 22026.5
exp(0.0) is 1
log(1.0) is 0
log(10.0) is 2.30259
log(Math.E) is 1
pow(2.0, 2.0) is 4
pow(10.0, 3.5) is 3162.28
pow(8, -1) is 0.125
The square root of 0 is 0
The square root of 1 is 1
The square root of 2 is 1.41421
The square root of 3 is 1.73205
The square root of 4 is 2
The square root of 5 is 2.23607
The square root of 6 is 2.44949
The square root of 7 is 2.64575
The square root of 8 is 2.82843
The square root of 9 is 3
Here's one random number: 0.820582
Here's another random number: 0.866157
You are not allowed to view links. Register or Login

La clase String

Ya se ha visto bastante pero vamos a profundizar un poco mas sobre como manejar una cadena de texto en Java.

Para eso tenemos la clase String que nos permite almacenar cadenas de texto, podemos crearlos implicitamente:

Código: (java) You are not allowed to view links. Register or Login
System.out.println("String implicito");
Donde perdemos la referencia a el, o explicito:

Código: (java) You are not allowed to view links. Register or Login
String s = "Explicito";
Donde conservamos un identificador que hace referencia a el (como cualquier otra cosa en Java se puede de las dos).

Tambien es posible inicializar un String a la forma de objetos:

Código: (java) You are not allowed to view links. Register or Login
String s=new String("Explicito");
Si queremos tener un String no inicializado usamos:

Código: (java) You are not allowed to view links. Register or Login
String s;
Pero tambien podemos inicializarlo como vacio:

Código: (java) You are not allowed to view links. Register or Login
String s="";
String s=new String();

Luego podemos hacer varias operaciones con el String por ejemplo:

Saber su longitud
Código: (java) You are not allowed to view links. Register or Login
String s="Hola soy un String";
int a = s.length();
(a=18, los espacios en blanco cuentan tambien)

Saber si empieza o termina con algun subString:

Código: (java) You are not allowed to view links. Register or Login
String s="Hola soy un String";
boolean b1 = s.startsWith("Hola");
boolean b2 = s.endsWith("String");
(los dos booleanos valdran true)

Buscar letras o subString dentro del String:

Código: (java) You are not allowed to view links. Register or Login
String s = "Hola soy un String";
int pos = s.indexOf('o'); //posicion de la primer 'o' (se va a el fin si no hay)
pos = s.indexOf('p', pos+1); //como empieza despues de la primera buscara la segunda
pos= s.indexOf("ola"); //posicion donde empieza ese substring

Algo fundamental y que por ahi confunde en Java es la comparacion entre dos String.

Si se quiere saber si dos String contiene lo mismo NO hay que hacer:

Código: (java) You are not allowed to view links. Register or Login
String s1="Hola";
String s2="Hola";
if(str1==str2){
System.out.println("Los Strings son los mismos");
}

ERROR con el operador == estan comparando los objetos, no el texto, de esta forma seran distintos, lo que hay que hacer es:

Código: (java) You are not allowed to view links. Register or Login

if( s1.equals(s2) ){
System.out.println("Ahora si esta bien");
}


Usar el metodo equals de la clase String, tambien existe equalsIgnoreCase que es para no darle importancia a mayusculas minusculas.

El operador == se usa si ustedes hacen algo asi:

Código: (java) You are not allowed to view links. Register or Login
String a = "Hola";
String b = a;

Ahi si usan el operador == les da true porque son los mismos objetos.

Tienen compareTo(String) para poder hacer un orden alfabetico (saber si un String es mas grande o no que otro alfabeticamente)

substring(int) o substring(int, int) para poder extraerle partes:

Código: (java) You are not allowed to view links. Register or Login
String a = "Hola";
String b = a.substring(1); //ola
String c = a.substring(1,2); //ol

Y tienen por ejemplo valueOf() para pasar de cualquier tipo a String.

Código: (java) You are not allowed to view links. Register or Login
int a=10;
String s = String.valueOf(a);

Y pueden concatenar Strings con el operador + como ya hemos visto o con concat().

Esta el metodo trim()

Código: (java) You are not allowed to view links. Register or Login
String trim()
Que retorna un String sin espacios al principio y al final:

Código: (java) You are not allowed to view links. Register or Login
class asd {
public static void main(String... args) {
String s = "   hola   ";
String sinEspacios = s.trim();
System.out.println(sinEspacios);
}
}
nota: trim() no saca los espacios dentro del String.

Otro metodo muy interesante es split() que sirve para "cortar" un String en pedacitos, indicando por donde se debe separar y devuelve un arreglo de Strings.

Código: (java) You are not allowed to view links. Register or Login
class asd {
public static void main(String... args) {
String s = "hola como te va";
String [] result = s.split(" ");
for (int x=0; x<result.length; x++) {
System.out.println(result[x]);
}
}
}

Lo que se puede poner dentro de split no se limita a otro String, sino que son expresiones regulares, probablemente mas adelante las veamos o sino investigaran por su cuenta.

Tienen toda la API aca:

You are not allowed to view links. Register or Login.

Una Aclaracion sobre los String
La clase String tiene una peculiaridad, es una clase inmutable que significa eso? que una ves que se crea no se puede modificar, solo podemos reemplazarlo.

Por ejemplo si tenemos:

Código: (java) You are not allowed to view links. Register or Login
String s = "Hola";

No se puede hacer algo del estilo:

Código: (java) You are not allowed to view links. Register or Login
s.setValue("Chau");

Osea un modificador de objeto que cambie el valor, pero si se puede hacer:

Código: (java) You are not allowed to view links. Register or Login
s = "Chau";

Cual es la diferencia?? como saben ese igual equivale a un new (recuerdan?):

Código: (java) You are not allowed to view links. Register or Login
String s="";
String s=new String();

Entonces al hacer igual se crea un nuevo objeto y listo caso arreglado, porque con el setValue() (que no existe es solo un ejemplo que estoy dando) se modificaria el objeto del principio.

Porque no se puede modificar un String?? bueno es para mantener la consistencia en el programa, como en Java todo se pasa por valor (es decir se pasa el dato en si, y no una copia del mismo) si se pasa un dato y luego se modifica el programa pierde consistencia, veamos un ejemplo.

Código: (java) You are not allowed to view links. Register or Login
class Saludo {
    private String palabra;
    public void setSaludo(String s) {
    this.palabra = s;
    }
    public String getPalabra() {
    return palabra;
    }
}

public class Main {
public static void main(String[] args) {
Saludo s = new Saludo();
String e = "hola";
s.setSaludo(e); //el saludo sera un hola
e.setValue("chau"); //si el string fuera mutable ahora valdria "chau" y este objeto es el que esta en Saludo
System.out.println(e); //Aca se muestra seguro "chau" por pantalla
System.out.println(s.getPalabra()); //Aca esta el problema, en relidad la clase saludo tenia un "hola" pero
//el objeto que tenia cambio a "chau" asi que mostraria "chau" cuando en realidad era un hola
}
}

Obviamente esono compila porque los String son inmutables, pero queda claro porque el programa pierde su consistencia.

StringBuffer y StringBuilder

Hay dos clases que son muy similares a la String que son StringBuffer y StringBuilder. Ambas tienen una caracteristica, que son mutables, es decir que podemos cambiar su contenido con los metodos

append(String) (agrega)
delete(int, int) (borra desde ese indice hasta ese otro)
insert(int, String) (agrega en esa posicion ese String)

Pero no es que la consistencia y bla bla bla, bueno estas clases estan para usar cuando queremos que un String pueda mutar (osea cambiar sin crear un nuevo objeto) pero puede que su programa en algun punto tenga problemas como los que explique asi que hay que saber cuando usarlos.

Cual es la diferencia entre estos dos.

Normalmente hay que usar StringBuilder, es mas rapida que la anterior.

Pero StringBuffer es la que hay que usar en (Algo que todavia no se explico pero si lo investigan mas adelante o ya saben otro lenguaje) entornos multi-hilo, osea que StringBuffer esta sincronizada, si no sabes nada de multihilo simplemente hace de cuanta por el momento que StringBuffer no existe :)

Aca esta la documentacion de los 2:

You are not allowed to view links. Register or Login.
You are not allowed to view links. Register or Login.

Saludos

PD. Un buen ejercicio que podrian hacer para practicar casi todo lo que se vio y aparte para aprender a penser en objetos es el siguiente:

Código: You are not allowed to view links. Register or Login
Una figura puede estar compuesta por otras figuras básicas, como por ejemplo: triángulos, elipses y cuadriláteros. Se
sabe además que un tipo particular de elipse es el círculo, mientras que un tipo particular de cuadrilátero es el
rectángulo. A su vez un tipo particular de rectángulo es el cuadrado. Por otra parte, los cuadriláteros y triángulos son
tipos de polígonos. Los polígonos tienen un número de lados, y dichos lados están definidos por 2 puntos. Un punto
está definido por una coordenada en el eje de las x, y otra en el eje de las y.

Una ves tengan definida la estructura desde el main podrian crear diferetes figuras con un nombre y sus caracteristicas como radio, o base y altura en fin, sus cosas depende de que sea, y calcular aereas y esas cosas que se les calcula a las figuras, estaria bueno que identifiquen que clases hay que hacer, cuales son abstractas, cuales no lo son, donde hay una relacion de herencia y donde no, como hacer un polimorfismo, manejo bien de las palabra private, public y protected, uso de package e import si lo ven nesesario, uso de this y super, uso de Strings para los nombres y Math para los calculos, en fin este ejemplo parace tenerlo todo, no se si nesesitaran algun arreglo, creo que no pero si lo ven nesesario usen nomas.

Estaria bueno que lo hagan para reafirmar todos los conocimientos

Si quieren postear su codigo primero lean el post de aca abajo ;)

Saludos
« Última modificación: Mayo 01, 2012, 06:45:34 pm por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #26 en: Abril 15, 2012, 08:20:06 am »
Comentarios y Convenciones de Programacion

Java usa de lleno el paradigma de programacion orientado a objetos, que surguio no tanto para facilitarle pensar un problema a un programador sino mas bien para poder hacer proyectos sumamente flexibles y extencibles.

Si alguien sabe algo de metodologias de desarollo de software sabra bien que la parte mas larga y tediosa del ciclo de vida de un software es el mantenimieto, gracias a una buena eleccion de clases y objetos se hace mucho mas simple poder modificar un software existente, pero hay algo mas que me gustaria explicarles que no tiene mucho que ver con la programacion y sin embargo sirve muchisimo para facilitar el proceso de mantenimieto a un software, y es:

Un codigo lindo bien comentado.

Lo primero es el estilo de programacion, para que todos nuestros codigos en Java se vean iguales a los codigos de otros programadores y para que puedas leer facilmente cualquier codigo.

Casi todos los lenguajes de enserio tienen dfinido su propio estilo de programacion, para programar en Java hay que tener en cuenta las siguientes convenciones:

Formato de líneas

1. No usar más de 80 caracteres por línea (imagen de tarjeta). De esta forma se pueden visualizar
las líneas completas con un editor de texto o en una hoja impresa tamaño DIN A4.

2. Cuando la línea sea mayor de 80 caracteres, divídala en varias partes, cada una sobre una línea.
Salte de línea al final de una coma o al final de un operador. Si se trata de una expresión con
paréntesis salte, si es posible, a línea nueva después de finalizar el paréntesis. Por ejemplo, casos
válidos serían, 

Código: (java) You are not allowed to view links. Register or Login
public void metodoHaceAlgo(int valor1, double valor2,
int valor3){

Código: (java) You are not allowed to view links. Register or Login
resultado = aux* (final-inicial+desplazamiento)
+ referencia;

3. Use líneas en blanco como elemento de separación entre bloques de código conceptualmente
diferentes.

4. Sangre(Idente) adecuadamente cada nuevo bloque de sentencias. Entre dos y cuatro espacios en blanco
son suficientes para cada nivel de sangrado. De esta forma se aprecia visualmente la diferencia
de nivel entre bloques de sentencias, sin rebasar, normalmente, los 80 caracteres por línea. A la
hora de sangrar, y para evitar problemas de compatibilidad entre editores de texto, use espacios
y no tabuladores. Por ejemplo,

Código: (java) You are not allowed to view links. Register or Login
public double calcularDescuento(double total) {

    int aux=0;

    if (total>LIMITE) {
        total = total * 0.9;
    }
    return total;

}

Ficheros

1. Incluya una sola clase o interfaz por fichero, o al menos una sola clase o interfaz pública.

2. Si hay comentarios globales para los contenidos del fichero colóquelos en primer lugar.

3. Si la clase forma parte de un paquete, la sentencia package deber ser la primera del fichero.

4. Si se importan paquetes, la sentencia import debe aparecer después de la sentencia package.

5. Coloque la declaración de las clases o interfaces a continuación de la sentencia package.

Clases

1. Coloque en primer lugar los comentarios sobre la clase (vea el apartado comentarios).

2. Coloque los atributos (datos) a continuación. Coloque primero las variables estáticas y a
continuación las variables de ejemplar en el orden: público (se recomienda no incluir variables
públicas), protegidas y privadas, es decir, public, protected y private en Java.

3.  A continuación se declaran los métodos, con los constructores en primer lugar. El resto de
métodos se colocará en orden de interrelación y no por visibilidad. Así, si un método público usa
dos métodos privados, se debería colocar primero el público seguido de los dos privados. La idea
es que al leer el código se siga con facilidad la funcionalidad de los métodos. Las
recomendaciones de los dos últimos puntos se resumirían de la forma siguiente,
Código: (java) You are not allowed to view links. Register or Login
class NombreClase {
    variables estáticas
    variables de ejemplar públicas (debe evitarse su uso)
    variables de ejemplar protegidas
    variables de ejemplar privadas

    métodos constructores
    resto de métodos

}

4. No deje espacio en blanco entre el identificador del método y los paréntesis, es decir, escriba,

Código: (java) You are not allowed to view links. Register or Login
public void nombreMetodo(int valor1, double valor2)
en lugar de,

Código: (java) You are not allowed to view links. Register or Login
public void nombreMetodo (int valor1, double valor2)
obsérvese el espacio en blanco delante de la apertura de paréntesis.

Visibilidad de miembros de clase


1. Los atributos (datos) deben declararse privados (private) excepto los que se pretenda que
sean accesibles por herencia que deben ser protegidos (protected). Se debe evitar el uso de
datos públicos.

2. Los procedimientos (métodos) de la interfaz pública deben declararse public, los de soporte
privados (private).

Identificadores

1. Escoja identificadores significativos y a ser posible breves. En cualquier caso prefiera la claridad
a la brevedad. Por ejemplo, es preferible el identificador,

Código: (java) You are not allowed to view links. Register or Login
integralIndefinida
que el de,
Código: (java) You are not allowed to view links. Register or Login
intInd
2. Para clases e interfaces escoja como identificador un sustantivo. Use minúsculas excepto para
la letra inicial. Si el identificador consta de varias palabras colóquelas juntas, con la inicial de
cada una en mayúsculas. Por ejemplo, serían identificadores apropiados,
Código: (java) You are not allowed to view links. Register or Login
class Cliente

class ClientePreferencial

3. Para las variables y objetos utilice identificadores en minúsculas. Si el identificador consta de
varias palabras se colocan separadas por el carácter de subrayado o bien todas seguidas. Es este
último caso, la primera de ellas se escribe en minúsculas y la inicial de las demás en mayúsculas.
Por ejemplo,

Código: (java) You are not allowed to view links. Register or Login
double valorFinal=0.0;
int cantidadFinal=0;
String nombre_cliente=”Aurora”;

4. Para las constantes, el identificador debe usarse en mayúsculas. Si el identificador consta de
varias palabras se separan con el carácter de subrayado. Ejemplo correctos serían,

Código: (java) You are not allowed to view links. Register or Login
final int MINIMO=100;
final double PRECISION=0.001;
final double ALTURA_MEDIA=29.5;

5. En el caso de los métodos, el identificador debe ser preferentemente un verbo y debe usarse en
minúsculas. Si el identificador contiene varias palabras, la inicial de todas las posteriores a la
primera va en mayúsculas. Ejemplos válidos serían,

Código: (java) You are not allowed to view links. Register or Login
public void introducir(double valor){
- - - cuerpo del método - - -
}

public double obtenerMedia(){
- - - cuerpo del método - - -
}

6. Para el identificador de los paquetes se recomienda usar minúsculas.

Declaraciones

1. Declare las variables al principio del bloque en el que se vayan a utilizar. En los métodos,
declare las variables al principio del método. Intente inicializar todas las variables que se
declaren.

2. En relación con el punto anterior, si en los bucles no se precisa que alguna variable exista antes
o después del mismo, declárela dentro del bucle.

3. Declare las matrices con los corchetes al lado del nombre del tipo y no del identificador, es decir,
con la sintaxis,
Código: (java) You are not allowed to view links. Register or Login
int [] producto;
y no como,

Código: (java) You are not allowed to view links. Register or Login
int producto [];
Sentencias de control

1. No use nunca saltos incondicionales. Más concretamente, no utilice la sentencia break excepto
en la sentencia switch, donde es forzoso hacerlo. Nunca use la sentencia continue.

2. No use más de un return en cada método y coloque éste al final del método.

3. Coloque la apertura de bloque ({ ) al final de la línea inicial de la sentencia. El fin de bloque
( } ) colóquelo en línea aparte y alineado con el principio de la sentencia. Si la sentencia de
control es un if-else la cláusula else debe comenzar en la línea siguiente al fin del bloque
de la cláusula if. Por ejemplo, escriba,

Código: (java) You are not allowed to view links. Register or Login
if (i==j) {
    dato=5;
}
else {
    dato=6;
}
en lugar de,

Código: (java) You are not allowed to view links. Register or Login
if (i==j)
{
    dato=5;
} else
{
    dato=6;
}

4. Ponga cada nuevo bloque de sentencias entre llaves aunque conste de una sola sentencia. Por ejemplo, escriba

Código: (java) You are not allowed to view links. Register or Login
if (i==j) {
    dato=5;
}
else {
    dato=6;
}

y no,

Código: (java) You are not allowed to view links. Register or Login
if (i==j)
    dato=5;
else
    dato=6;

5. Una recomendación muy frecuente es la siguiente. En los if anidados si un if interno
corresponde a una cláusula else externa se coloca el if a continuación y en la misma línea
que el else. El bloque de este nuevo if se cierra al nivel del else anterior. Por ejemplo,

Código: (java) You are not allowed to view links. Register or Login
if (dato1==0) {
    resultado=total;
} else if (dato1>10) {
    resultado = total*0.8;
} else {
    resultado = total*0.95;
}

Aunque ésta es una recomendación muy extendida que intenta que los if se interpreten en
cascada, aquí recomendamos el formato obtenido al aplicar las normas del apartado 3 de esta
sección, que para el ejemplo anterior produciría el siguiente resultado,

Código: (java) You are not allowed to view links. Register or Login
if (dato1 == 0){
    resultado=total;
}
else {
    if (dato1 > 10) {
        resultado = total*0.8;
    }
    else {
        resultado = total*0.95;
    }
}

Este formato permite identificar el alcance de las distintas estructuras if-else por el nivel
de sangrado de las sentencias.

Documentación

1. Documente el código. No se trata de sustituir la información de análisis y diseño, pero la
documentación interna es un complemento que puede servir como guía del sistema en el peor
de los casos, cuando no hay otra documentación disponible.

2. Como cabecera de una clase incluya como información el autor o autores, la fecha de la última
modificación, el propósito general de la clase y una breve explicación de los datos y métodos
incorporados.

3. Como cabecera de los métodos cuya acción no sea evidente indique el autor o autores, la fecha
de la última modificación, el propósito del método, el significado de los parámetros formales,
el significado de la información devuelta con return y las excepciones que se capturen.

4. En el cuerpo de los métodos use comentarios para indicar el propósito de las tareas que no sean
evidentes, tales como algoritmos específicos. En cualquier caso aumente la legibilidad del código
usando identificadores significativos para variables o métodos.


Estan sacadas de You are not allowed to view links. Register or Login.

Si bien son varias para acordarselas a todas de una a la larga estaria bueno que se aprendan la mayoria, no es tan complicado y algunas son muy generales para otros lenguajes, y otras son insignificantes y no hace falta seguirlas, sin embargo si usan algun IDE como eclipse, creo que tiene un plugin que da formato al codigo para que comple gran parte de las explicadas anteriormente, ademas existen programas embellecedores de codigo y cosas por el estilo, de todas formas no hace falta usarlo una ves que se aprenden esto.

Si quieren un documento mas serio sobre esto,You are not allowed to view links. Register or Login.

Eso por un lado, con eso van a conseguir un codigo lindo, ahora otra cosa importante es comentar, comentar no solo sirve para explicar esa linea de codigo complicada que solo un comentario sirve para que nos demos cuenta que hace.

Si ustedes tienen que agarrar codigo de otra persona y entenderlo, y esto codigo esta perfecto pero no tiene ningun comentario, a la larga despues de seguir con la mirada fija linea por linea se van a ir dando cuanta que es cada variable, que hace cada metodo, para que sirve cada uno de sus atributos y que retorna, y que cosa esta modelando cada clase.

Ahora, si ustedes justo arriba de un metodo que tiene, digamos, 20 lineas de codigo facil de entender, tienen un comentario que dice:  "este metodo calcula el promedio entre dos numeros y lo retorna". ya esta, se entendio que hace todo eso con solo ese poquito, asi que comentar es muy importante.

Existe algo llamado generadores de documentacion, si todos los metodos clases y variables importantes estan documentados de forma correcta, no haria ni falta leer el codigo para buscar los comentarios, si alguien se encargara de parsearlos y ordenarlos con eso es mas que suficiente, Java tiene algo conocido como JavaDoc que es una aplicacion que hace mas o menos eso, vamos a aprender a manejarla.

Primero veamos como comentar:

Código: (java) You are not allowed to view links. Register or Login
//comentario de una linea
(estos son comentarios que no queremos que aparescan en JavaDoc pero que creamos utiles en el programa, por ejemplo decir que hace una linea de codigo o algo por el estilo)

Código: (java) You are not allowed to view links. Register or Login
/*
Comentario de varias lineas
1
2
*/
(estos comentarios son usados para lo mismo de arriba pero los IDEs dan la posibilidad de esconderlos, asi que se vuelve practico cuando queremos programar y no leer comentarios)

Código: (java) You are not allowed to view links. Register or Login
/**
Comentario de varias lineas que va a ser parseado por JavaDoc
1
2
*/
(notar que tiene 2 **)

Para comentar:

Hay que comentar cada clase, metodo y variable con JavaDoc, y tambien se puede comentar al principio de un fragmento de código no evidente o a lo largo de los bucles, y si hacemos algo raro tambien esta bueno comentar.

Antes de cada clase tiene que especificar que hace de esta forma.

Código: (java) You are not allowed to view links. Register or Login
/**
Esta clase se usa para guardar los datos de un pasajero de un avion
*/
public class Pasajero { ... }

Lo mismo con los metodos y variables.

Ademos JavaDoc tiene algunas etiquetas que hacen aun mas facil de reconecer rapido lo que importa, las etiquetas son:

@author name    -Se usa para indicar el autor, antes de clases, interfaces o enums   
@version version    -Se usa para indicar la version del software antes de lo mencionado arriba
@since since-text    -Se usa para indicar desde cuando esta esa funcionalidad en cualquier lado
@see reference    -Se usa para proporcionar otra fuente de informacion a lo que se va a ver.    
@param name description  -Se usa para indicar un parametro de un metodo
@return description  -Se usa para indicar el valor de retorno de un metodo
@exception classname description
@throws classname description  -Tanto esta como la anterior se usa en un metodo para indicar si lanza alguna excepcion   
@deprecated description  - Se usa en un metodo para indicar que ya esta viejo (en el sentido de que uno nuevo lo mejora)

Esos son los principales hay otro mas, por ejemplo para poner links etc.

Bueno ya con eso mas o menos para poder programar, despues pueden pasar el JavaDoc y ver que les genera un HTML con la documentacion (es igual a doxygen o alguno similar si ya los probaron).

Como usar el JavaDoc no lo explico, es muy facil, pueden buscar en internet.

Aca les dejo un ejemplo (completo por demas) de una documentacion de una clase y unos metodos (en ingles)

Código: (java) You are not allowed to view links. Register or Login
/**
 * Graphics is the abstract base class for all graphics contexts
 * which allow an application to draw onto components realized on
 * various devices or onto off-screen images.
 * A Graphics object encapsulates the state information needed
 * for the various rendering operations that Java supports.  This
 * state information includes:
 * <ul>
 * <li>The Component to draw on
 * <li>A translation origin for rendering and clipping coordinates
 * <li>The current clip
 * <li>The current color
 * <li>The current font
 * <li>The current logical pixel operation function (XOR or Paint)
 * <li>The current XOR alternation color
 *     (see <a href="#setXORMode">setXORMode</a>)
 * </ul>
 * <p>
 * Coordinates are infinitely thin and lie between the pixels of the
 * output device.
 * Operations which draw the outline of a figure operate by traversing
 * along the infinitely thin path with a pixel-sized pen that hangs
 * down and to the right of the anchor point on the path.
 * Operations which fill a figure operate by filling the interior
 * of the infinitely thin path.
 * Operations which render horizontal text render the ascending
 * portion of the characters entirely above the baseline coordinate.
 * <p>
 * Some important points to consider are that drawing a figure that
 * covers a given rectangle will occupy one extra row of pixels on
 * the right and bottom edges compared to filling a figure that is
 * bounded by that same rectangle.
 * Also, drawing a horizontal line along the same y coordinate as
 * the baseline of a line of text will draw the line entirely below
 * the text except for any descenders.
 * Both of these properties are due to the pen hanging down and to
 * the right from the path that it traverses.
 * <p>
 * All coordinates which appear as arguments to the methods of this
 * Graphics object are considered relative to the translation origin
 * of this Graphics object prior to the invocation of the method.
 * All rendering operations modify only pixels which lie within the
 * area bounded by both the current clip of the graphics context
 * and the extents of the Component used to create the Graphics object.
 *
 * @author      Sami Shaio
 * @author      Arthur van Hoff
 * @version     %I%, %G%
 * @since       1.0
 */
public abstract class Graphics {

    /**
     * Draws as much of the specified image as is currently available
     * with its northwest corner at the specified coordinate (x, y).
     * This method will return immediately in all cases, even if the
     * entire image has not yet been scaled, dithered and converted
     * for the current output device.
     * <p>
     * If the current output representation is not yet complete then
     * the method will return false and the indicated
     * {@link ImageObserver} object will be notified as the
     * conversion process progresses.
     *
     * @param img       the image to be drawn
     * @param x         the x-coordinate of the northwest corner
     *                  of the destination rectangle in pixels
     * @param y         the y-coordinate of the northwest corner
     *                  of the destination rectangle in pixels
     * @param observer  the image observer to be notified as more
     *                  of the image is converted.  May be
     *                  <code>null</code>
     * @return          <code>true</code> if the image is completely
     *                  loaded and was painted successfully;
     *                  <code>false</code> otherwise.
     * @see             Image
     * @see             ImageObserver
     * @since           1.0
     */
    public abstract boolean drawImage(Image img, int x, int y,
                                      ImageObserver observer);


    /**
     * Dispose of the system resources used by this graphics context.
     * The Graphics context cannot be used after being disposed of.
     * While the finalization process of the garbage collector will
     * also dispose of the same system resources, due to the number
     * of Graphics objects that can be created in short time frames
     * it is preferable to manually free the associated resources
     * using this method rather than to rely on a finalization
     * process which may not happen for a long period of time.
     * <p>
     * Graphics objects which are provided as arguments to the paint
     * and update methods of Components are automatically disposed
     * by the system when those methods return.  Programmers should,
     * for efficiency, call the dispose method when finished using
     * a Graphics object only if it was created directly from a
     * Component or another Graphics object.
     *
     * @see       #create(int, int, int, int)
     * @see       #finalize()
     * @see       Component#getGraphics()
     * @see       Component#paint(Graphics)
     * @see       Component#update(Graphics)
     * @since     1.0
     */
    public abstract void dispose();

    /**
     * Disposes of this graphics context once it is no longer
     * referenced.
     *
     * @see       #dispose()
     * @since     1.0
     */
    public void finalize() {
        dispose();
    }
}

Fijense que pueden usar meta-etiquetas HTML en los comentarios y luego JavaDoc las interpreta.

No se si es nesesario tanto comentario, pero si es una clase esencial, o un metodo importante esta bueno que lo comenten.

Ese ejemplo esta sacado de la guia oficial de documentacion, que es You are not allowed to view links. Register or Login.

Saludos
« Última modificación: Abril 18, 2012, 05:33:14 pm por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #27 en: Abril 18, 2012, 03:56:22 pm »
Clases internas

Es posible declarar una clase dentro de otras clases, sin embargo esta tecnica es criticada por algunos y querida por otros, y puede llevar tanto a la confuncion como a la mejor interpretacion de un codigo, todo depende de como se utilizen. Tengan en cuanta que lo que esta dentro de una clase es otra clase y no un objeto.

Las hay de 4 tipos diferentes:

Miembro
Estatica
Local
Anonima


La Miembro es la que esta dentro de otra clase asi como suena (ya la veremos), la estatica es la que tiene antepuesto la palabra static, la local es la que esta dentro de un metodo y la anonima esla que no tiene un identificador o nombre asosiado.

Antes de continuar voy a postear un codigo simple de una clase regular para que vean como es, porque seguro se lo estan confundiendo con un objeto.

Código: (java) You are not allowed to view links. Register or Login
public class Afuera {
    class Adentro {
        ....
    }
}

Ya vieron que es algo extraño. Bueno que cosas son las que hacen que tengamos que usar una clase interna? en realidad no esta muy claro y de hecho no sabria de decirles bien cuando se debe usar una.

Por ejemplo pueden usar una clase interna anonima (que ya las veremos) para abrebiar un poco de codigo y evitar toda una declaracion de una clase que carece de importancia. (ya veremos un ejemplo)

Pueden usar la clase externa como una contenedora de clases que estan relacionadas, para poder hacer referencia a todas ellas bajo un mismo identificador, por ejemplo, si estamos haciendo un sistema de mails tendriamos la clase Enviar, la Recibir, la Guardar, etc. Podriamos poner todas ellas dentro de una clase Correo para que este mas organizadas (en realidad esto no es muy nesesario pero es un posible uso).

Ahora veamos dos caracteristicas de estas clases que daran lugar a algunos usos mas importantes.

Una clase interna puede acceder a todos los datos de la clase padre, incluso si estos estan declarados como private. (es algo similar al concepto de clase friend en C++)

Esto sirve en casos muy particulares en que queremos que dos clases esten muy relacionadas entre si. Por ejemplo, recordemos lo de la clase contenedora, si uno define una variable "usuario" que indica el nombre de la persona que esta manejando actualmente todo el correo, en la clase externa, todas las clases internas pueden acceder a esa variable que seria como una especie de variable global para ellas.

Ademas permite que por ejemplo, si manejamos una estructura de datos como es un arreglo por ejemplo, poder desacoplar aun mas dentor dela clase del arreglo lo que es la idea abstracta de un arreglo, a lo que es un algoritmo de busqueda en una estructura particular.

A mi modo de ver todavia no tiene muchas ventajas, puede que alguna ves en la vida sea nesesario que dos clases esten tan "intimamente" vinculadas que una nesesite poder tener acceso a sus datos privados pero eso es una en un millon.

La siguiente caracteristica de las clases internas es la que a mi modo de ver la da mas funcionalidad a estas clases.

No se puede crear una instancia de una clase interna si no se ha creado una instancia de la clase interna.

Esta caracteristica esta relacionada con esta otra:

No se pueden definir ni vriables ni metodo static en una clase interna.

Esto hace que no se pueda meter un main y por ende si o si tiene que existir una instancia de la clase externa para poder crear a la de la clase interna.

Para que sirve esto?
Basicemente si existe una clase que depende de otra para su existencia no hay forma que de hacer que no se puedan crear instancias de ella sin que existan de la otra, hasta ahora...

Supongamos (y no se me ocurre un buen ejemplo) que tenemos una clase Cabeza, la cabeza pertenece a una persona que dicho sea de paso esta definida en la clase Persona.

Ahora bien podemos crear una persona y luego crear su cabeza y hacer todo lo que queramos, pero no seria correcto que podamos crear la cabeza si no creamos a la persona porque no tendria sentido, entonces podemos usar esta tecnica para solucionar este problema.

Nota
Si alguien ya uso las Collections de Java o ha usado estructuras de datos de otros lenguajes como por ejemplo C++ las que tiene en stl containers, o alguna otra cosa de otro lenguaje, habra notado es uso de iteradores, los iteradores sirven para recorrer una estructura dada, un iterador eta intimamante relacionado con la clase que define la estructura que recorre porque el accede a sus datos, ademas no se puede definir un iterdor de nada, un iterador es siempre de alguna estructura. Este es el caso mas visible del uso de clases internas.

Dejando de lado un poco la filosofia de porque se usan vamos a ver como se trabaja con ellas aunque quizas nunca mas lo hagamos en la vida =D

Las clases internas normales

Las clases internas normales son las que mas o menos introducimos y la definicion que ya la vimos era de este estilo:

Código: (java) You are not allowed to view links. Register or Login
public class Afuera {
    class Adentro {
        ....
    }
}

Veamos un ejemplo de uso simple:

Código: (java) You are not allowed to view links. Register or Login
public class Afuera {
    private int x = 0;

    class Adentro{
        public void mostrar(){
            System.out.println("El valor es: "+ x);
        }
    }

    public static void main(String[] args) {
        Afuera af = new Afuera();
        Afuera.Adentro ad = af.new Adentro();
        ad.mostrar();
    }

}

Como pueden ver solo podemos instanciarla si esta instanciada la de afuera (miren que raro lo del segundo new) y ademas desde una clase pudimos mostrar un atributo private de otra.

Tambien podemos crear la instancia de esta forma que es un poco mas rapido:

Código: (java) You are not allowed to view links. Register or Login
Afuera.Adentro ad = new Afuera().new Adentro();
Una cosa importante se da con la palabra reservada this, ya saben lo que hace, y se entaran imaginando como 5 variables distintas en un mismo lugar con un mismo nombre xD

La forma de referenciar a las variables no cambia, solo se agrega un caso que es la variable del padre, en este caso con this no alcanza hay que usar: Afuera.this mas lo que queramos (osea NombreDeClaseExterna.this)

Muy probablemente no usemos estas clases pero esta bueno saberlas para entender el codigo de las demas personas y algunas cuestiones de las APIs de Java, por ejemplo los eventos de las interaces gracias de Java usan clases internas.

Otra aclaracion adicional es que la maquina virtual Java no sabe nada de estas clases, para ella simplemete son clases normales y hasta crea un nuevo archivo.class con un nombre que es contenedora$contenida.class

Y otra mas que que una clase interna es independiente a la externa en cuanto a lo que se refiere a herencia e implementacion de interfaces (por ahi esto llega a dar mas utilidad en cuando a lo que hablamos de uso de los datos privados de la clase global).


Las clases internas static

Son tambien conocodas como calses anidadas y como ya saben tiene la palabra reservada static delante de la definicion.

En realidad no es que la clase sea estatica, porque eso no existe, lo que quiere decir es que la clase a continueacion es un miebro estatico de la clase contenedora.

En que cambia??

No nesesitamos referencia de la contenedora, podemos haceder a esa clase cuando queramos.
No podemos acceder a las variables ni metodos de la contenedora a no ser que sean static

veamos un ejemplo:

Código: (java) You are not allowed to view links. Register or Login
class A {
    int i=1; // variable miembro de objeto
    static int is=-1; // variable miembro de clase
   
    public A(int i) {
        this.i = i;
    }

    // a los métodos de la clase contenedora hay que pasarles referencias
    // a los objetos de la clase interna static
    public void printA(Bs unBs) {
        System.out.println("i="+ i +" unBs.j="+unBs.j);
    }

    // definición de una clase interna static
    static class Bs {
       int j=2;
        public Bs(int j) {
            this.j = j;
        }
     
       // los métodos de la clase interna static no pueden acceder a la i
       // pues es una variable de objeto. Sí pueden acceder a is
        public void printBs() {
            System.out.println(" j=" + j + " is=" + is);
        }
    }

}

class ClasesIntStatic {
    public static void main(String [] arg) {
        A a1 = new A(11),
           a2 = new A(12);
        System.out.println("a1.i=" + a1.i + " a2.i=" + a2.i);
        // dos formas de crear objetos de la clase interna static
       
        A.Bs b1 = new A.Bs(-10); // necesario poner A.Bs
        A.Bs b2 = a1.new Bs(-11); // b2 es independiente de a1
        // referencia directa a los objetos b1 y b2
        System.out.println("b1.j=" + b1.j + " b2.j=" + b2.j);

        // los métodos de la clase interna acceden directamente a las variables
        // de la clase contenedora sólo si son static
        b1.printBs(); // escribe: j=-10 is=-1
        b2.printBs(); // escribe: j=-20 is=-1
       
        // a los métodos de la clase contenedora hay que pasarles referencias
        // a los objetos de la clase interna, pera que puedan identificarlos
        a1.printA(b1); // escribe: i=11 unBs.j=-10
        a1.printA(b2); // escribe: i=11 unBs.j=-11
    }
}

*Ejemplo extraido de "Aprenda Java como si estubiera en primero"

Si es que no se pierden creo que deja bien en clara como es que se usa y todas sus caracteristicas.

Tambien se pueden definir interfaces de este tipo pero ya es mucho lio para explicar xD

Como les venia diciendo, aca la tienen explicada, ustedes veran para que les sirve todo esto.

Las clases internas locales (dentro de metodos)


Estas clases se declaran dentro de un metodo.

Solo son visibles desde ese metodo, no desde la clase externa como veniamos viendo, ademas de acceder a las variables de la clase tambien tiene acceso a las variables del metodo y a sus argumentos solo si fueron declarados como final

Aca, la palabra this se maneja igual que como lo vimos para hacer referencia hacia afuera.

No se puede definir nada static (como las primera) y algo que cambio es que no podemos poner un modificador de acceso (public, protected, private) porque estamos dentro de un metodo.

Vemos el ejemplo de Aprenda Java como si estubiera en primero:

Código: (java) You are not allowed to view links. Register or Login
class A {
    int i=-1; // variable miembro

    public A(int i) {
        this.i = i;
    }

    public void getAi(final long k) {
        final double f=3.14;
        class BL {
            int j=2;
            public BL(int j) {
                this.j = j;
            }

            public void printBL() {
                System.out.println(" j="+j+" i="+i+" f="+f+" k="+k);
            }
        }

        BL bl = new BL(2*i); // se crea un objeto de BL
        bl.printBL(); // se imprimen los datos de ese objeto
    }
}


class ClasesIntLocales {
    public static void main(String [] arg) {
        A a1 = new A(-10);
        A a2 = new A(-11);
        a1.getAi(1000);
        a2.getAi(2000);
    }
}

Devuelta les digo, busquen para que lo pueeden usar.

Las clases internas anonimas


Son clases como las que venimos viendo pero que no hace falta nombrarlas, y son las que mas se usan en el sistema de eventos de interfaces graficas de la API de java. En este caso el archivo que se genera es ClaseContenedora$1.class para la primer clase.

Como ya explique se usan cuando no es nesesario toda una definicion porque hay muy poco codigo, vamos a ver un ejemplo de lo que seria los eventos de una interfaz grafica:

Código: (java) You are not allowed to view links. Register or Login
Boton.addActionListener( new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        //Aca ponemos lo que queremos que pase cuando se apreta el boton
    }
});

Bueno no le demos sentido al codigo porque todavia no sabemos nada de interfaces graficas, y tampoco nos asustemos, si lo vemos con una clase definida seria algo asi:

Código: (java) You are not allowed to view links. Register or Login
Boton.addActionListener( Clase );
Pero como no queremos defirnir la clase porque es porque es poqueto codigo se hace todo de una, se define uan clase y se le mete un metodo, no voy a explicar el funcionamiento de nada porque eso corresponde al capitulo de interfaces graficas =D pero noten que se usa con un new al comienzo.

Bien eso es todo, como ya les dije, quizas nunca las usen en sus programas porque no tienen una utilidad tan significativa, sin embargo como vimos en la API de Java las hay y por eso es importante conocerlas, ademas si algun dia ven un codigo con estas clases y aca no se las explique les iba a parecer que eso no compilaria y se sorprenderian cuando salga todo andando bien xD

Si les interesa este tema pueden buscar mas en internet, sobre todo articulos en ingles, por ejemplo You are not allowed to view links. Register or Login esta muy completo.

Saludos

« Última modificación: Abril 19, 2012, 09:20:00 am por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #28 en: Abril 18, 2012, 08:17:50 pm »
Posible solucion al ejercicio propuesto

Si vienen siguiendo el curso se habran encontrado con este ejercicio:

Una figura puede estar compuesta por otras figuras básicas, como por ejemplo: triángulos, elipses y cuadriláteros. Se
sabe además que un tipo particular de elipse es el círculo, mientras que un tipo particular de cuadrilátero es el
rectángulo. A su vez un tipo particular de rectángulo es el cuadrado. Por otra parte, los cuadriláteros y triángulos son
tipos de polígonos. Los polígonos tienen un número de lados, y dichos lados están definidos por 2 puntos. Un punto
está definido por una coordenada en el eje de las x, y otra en el eje de las y.

Una ves tengan definida la estructura desde el main podrian crear diferentes figuras con un nombre y sus caracteristicas como radio, o base y altura en fin, sus cosas depende de que sea, y calcular aereas y esas cosas que se les calcula a las figuras.

Voy a poner una posible solucion para que vean mas o menos como seria.

Primero vamos a identificar que clases intervienen.

Sabemos que hay muchas figuras las cuales son: triángulos, elipses y cuadriláteros. Algunas mas: círculo, rectángulo, cuadrado.

Algo es mas que claro, todas esas son Figuras, asi que no estaria mal definir una clase Figura, y otra Poligono que tambien aparecio por ahi. Ademas nos dijeron que los poligonos se componen de un numero de Lados (o Lineas) y que estas Lineas se componen de 2 Puntos.

Asi que en un primer momento estariamos pensandoen programar las clases:

Triangulo, Elipse, Cuadrilatero, Circulo, Rectangulo, Cuadrado, Figura, Poligono, Linea y Punto. 

Ahora vamos a ver que clase tiene que ser abstracta y cual no lo debe ser.

Aca viene un poco en juego cuanto es lo que quieran implementar (yo en particular quiero trabajar poco) porque por ejemplo, los poligonos existen, asi que no deberia de ser abstracta, pero en realidad un poligino es un conjunto de otras figuras, asi que si estubieran implementadas todas esas figuras poligono deberia ser abstracta (aca no vamos a implementar todas pero de todas formas la voy a hacer abstracta porque no quiero calcular el area de un poligono, si ustedes piensan lo contrario pueden hacer los cambios).

Pensando de esta manera, una clase abstracta seria Figura, ya que no puedo calcular el area de una Figura, tengo que saber de que se trata.

Con cuadrilatero pasa lo mismo que con poligono, si bien se puede calcular el area de un cuadrilatero, se puede tambien representar todos los tipos de cuadrilateros, asi que para yo trabajar menos propongo hacerla abstracta. y por ahora ya es suficiente.

Y por ultimo identifiquemos en donde hay una relacion de herencia y una relacion de uso.

Aca tenemos mucho trabajo, en un primer momento sabemos que todo lo que hay aca SON figuras, eso nos indica que la clase Figura va a tener muchos hijos.

Vamos por dimensiones y complejidad.

Primero el Punto, es la figura mas simple, sera hijo directo de figura.

Linea, sera hijo directo de Figura, y ademas Linea va a utilizar a la clase Punto (recuerden que una linea son dos puntos).

Circulo sera hijo directo de Figura? NO, porque? porque comviene que hijo sea hijo de Elipse y Elipse sea de Figura.

Cuadrilateros y Triangulos que sean hijos de Poligono y Poligono hijo de Figura, Asi Figura tendra 4 hijos. Ademas Poligono usara a la clase Linea.

Y lo que falta es Rectangulo que sera hijo de Cuadrilatero y Cuadrado que sera hijo de Rectangulo.

Una ves tengamos esto es cuantion de empezar a programar las clases, podemos empezar a programar las mas "alta" o abstracta, o las mas detalladas y concretas, (depende si ustedes son bottom-up o top-down). Yo voy a empezar por la mas abstracta porque creo que todos lo entienden mejor asi.

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Clase Figura define el comportamiento abstracto de una Figura cualquiera

public abstract class Figura {

protected String nombre; //Nombre de cualquier figura

//Constructor, recibe como parametro el nombre de la figura
public Figura(String nombre) {
this.nombre = nombre;
}

//retorna el nombre de la figura
public String getNombre() {
return nombre;
}

//retrna el area de la figura, no se implementa aca
public abstract double getArea();

}

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Clase Punto define el comportamiento de un punto, hereda de Figura

public class Punto extends Figura {

private double x , y; //son las coordenadas x e y

//constructor recibe por parametro el nombre y las dos coordenadas
public Punto(String nombre, double x, double y) {
super(nombre); //se llama al constructor de Figura con el nombre
this.x = x;
this.y = y;
}

//retorna la coordenada X
public double getX() {
return x;
}

//retorna la coordenada Y
public double getY() {
return y;
}

//Un punto no tiene area
public double getArea() {
return 0.0;
}

}

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Clase Lina define el comportamiento de un linea, hereda de Figura

public class Linea extends Figura {

private Punto p1, p2; //Son los dos punto extremos de una linea


//Constructor recibe por parametro el nombre y los dos puntos
public Linea(String nombre, Punto p1, Punto p2) {
super(nombre); //Se llema a el contructor de Figura
this.p1 = p1;
this.p2 = p2;
}

//se obtiene el primer punto
public Punto getP1() {
return p1;
}

//se obtiene el segundo punto
public Punto getP2() {
return p2;
}

//devuelve el largo de la linea (distancia euclidia entre dos puntos)
public double getDistancia() {
return Math.sqrt( Math.pow( p1.getX() - p2.getX(),2) +
Math.pow( p1.getY() - p2.getY(),2));
}

//el area de una linea es 0
public double getArea() {
return 0.0;
}

}

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Clase que describe cualquier tipo de poligono, hereda de Figura
//Es abstracta porque no se van a crear poligonos, pero
//si se quieren poder crear poligonos, hay que implementar
//el metodo getArea()

public abstract class Poligono extends Figura {
protected Linea [] lados; //un conjunto(arreglo) de lineas definen a un poligono

//Constructor que recibe el nombre y un arreglo de lineas para crear el poligono
public Poligono(String nombre, Linea[] lados) {
super(nombre);
this.lados = lados;
}

//otro constructor que solo pide el nombre
//notar que es protected asi que solo lo pueden llamar los hijos
//ver clase "Cuadrilatero" para entender porque
protected Poligono(String nombre) {
super(nombre);
}

//metodo para asignar un conjunto de lineas al poligono
protected void setLados( Linea[] lados ) {
this.lados = lados;
}

//retorna el array con todas las lineas
public Linea[] getLados() {
return lados;
}

//getArea se mantiene abstracta
}

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Clase que describe el comportamiento de un cuadrilatero cualquiera, herede de poligono

public abstract class Cuadrilatero extends Poligono {
//No hay variables porque poligono engloba todo.

//El constructor recibe el nombre y 4 lineas
public Cuadrilatero(String nombre, Linea l1, Linea l2, Linea l3, Linea l4) {
super( nombre ); //se llama al constructor de solo nombre
setLados(getArray(l1,l2,l3,l4)); //se definen los lados del poligono
}

/*NOTA: notar que no se usa el contructor con todos los datos, porque
como recibimos 4 lados y tenemos que pasarle un array, tendriamos
que trasformarlo primero, y super es la primer linea que tiene
que ser ejecutada, por eso se usa el contructor por nombre
y luego se genera el array y se lo pasa, nadie mas que los
hijos pueden hacer esto, para usar el cuadrlatero de afuera)
hay que usar el constructor completo (y hacer que la clase no sea
abstracta), esto igual sirve porque desde los hijos aseguramos
que vamos a asignar los lados. */


//metodo para pasar 4 lineas a un array de lineas.
//es private para que solo lo pueda usar cuadrilatero, porque es
//un porceso interno que se debe hacer
private Linea[] getArray(Linea l1, Linea l2, Linea l3, Linea l4) {
Linea[] lados = {l1,l2,l3,l4};
return lados;
}

//Sigo arrastarando getArea como abstracta

}

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Define el comportamiento de rectangulo, hereda de cuadrilatero

public class Rectangulo extends Cuadrilatero {
//no hay variables, poligono ya tiene todo

//un rectangulo se crea a partir de solo dos lados
public Rectangulo(String nombre, Linea l1, Linea l2) {
super( nombre, l1, l2, l1, l2 ); //aca se multiplican por dos
}

//el area del rectangulo es base x altura
//se agarran l1 y l2 que son lineas, se calcula su longitud
//y se multiplica
public double getArea() {
return lados[0].getDistancia() * lados[1].getDistancia();
}

}

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Comportamieto de una elipse, hereda de Figura

public class Elipse extends Figura {
protected Linea l1 ,l2; //una elipse son dos lineas que representan
//el semi-eje major y el semi-eje menor (hay mas formas de armar una elipse)

//constructor pide nombre y dos semiejes
public Elipse(String nombre, Linea l1, Linea l2) {
super(nombre);
this.l1 = l1;
this.l2 = l2;
}

//retorna semieje 1
public Linea getL1() {
return l1;
}

//retorna semieje2
public Linea getL2() {
return l2;
}

//retorna el area, semieje1 * semieje2 * pi
public double getArea() {
return l1.getDistancia() * l2.getDistancia() * Math.PI;
}

}

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Comportamieto de un circulo, hereda de elipse

public class Circulo extends Elipse {
//un circulo es un caso particular de la elipse donde los semiejes son iguales

public Circulo(String nombre, Linea radio) {
super(nombre, radio, radio); //se arma una elipse circular
}

//no hay que sobreescribir el area porque el de la elipse es el mismo
//recuerden pi por radio cuadrado, en realidad son los dos semiejes.
}

Código: (java) You are not allowed to view links. Register or Login
package Geometria;

//Comportamieto de un cuadrado, hereda de rectangulo

public class Cuadrado extends Rectangulo {
//un cuadrado es un caso particular del rectangulo donde todos los lados son iguales

public Cuadrado(String nombre, Linea lado) {
super(nombre, lado, lado); //se arma una rectangulo cuadrado
}

//no hay que sobreescribir el area porque el del rectangulo es el mismo
//recuerden base al cuadrado es lo mismo que base por altura
}

Este seria el main

Código: (java) You are not allowed to view links. Register or Login
import Geometria.*;
import java.util.Scanner;
 
public class FigurasGeometricas {


   
    public static void main(String[] args) {
    Punto p0 = new Punto("p00", 0.0 , 0.0);//se crea un ponto en 0,0
    Punto p1 = new Punto("p01", 0.0 , 1.0);//se crea un ponto en 0,1
    Punto p2 = new Punto("p10", 2.0 , 0.0);//se crea un ponto en 2,0
    Punto p3 = new Punto("p11", 2.0 , 1.0);//se crea un ponto en 2,1
    Linea l0 = new Linea("l01", p0, p2);//se crea una linea de longitud 2
    Linea l1 = new Linea("l23", p2, p3);//se crea una linea de longitud 1
    Rectangulo r0 = new Rectangulo("r01", l0, l1); //se crea un rectangulo con base 1 y altura 2
    System.out.println("El area del rectangulo: " + r0.getNombre() + " Es " + r0.getArea());
    Elipse e0 = new Elipse("e01" , l0, l1); //se crea una elipse con 2 y 1 como semiejes
    System.out.println("El area de la elipse: " + e0.getNombre() + " Es " + e0.getArea());
    Circulo c0 = new Circulo("e01" , l0); //se crea un circulo con  radio 2
    System.out.println("El area del circulo: " + c0.getNombre() + " Es " + c0.getArea());
    Cuadrado c1 = new Cuadrado("c0", l0); //se crea un cuadrado con lados de 2
    System.out.println("El area del cuadrado: " + c1.getNombre() + " Es " + c1.getArea());
   
//Ejemplo de polimorfismo
Figura f; // f es del tipo figura (abstracto), no es posible hacer "new Figura"
Scanner reader = new Scanner(System.in);
int opcion = 0;

System.out.println("Que figura queres crear?: 1=rec, 2=Elip, 3=Circ, 4=Cuad");

do {
try {
opcion = reader.nextInt();
} catch(Exception err) {
System.out.println("Debe ser un numero");
reader.next(); //ya saben que es esto, miren los otros ejemplos
}

} while ( opcion<1 || opcion>4 );

//Figura se iguala a alguna instancia de sus hijas (o nietas xD)
switch(opcion) {
        case 1: f = new Rectangulo("r01", l0, l1); break;
            case 2: f = new Elipse("e01" , l0, l1);  break;
            case 3: f = new Circulo("e01" , l0);  break;
            case 4: f = new Cuadrado("c0", l0); break;
            default : System.out.println("Algo salio mal");
        }

//Puede ser nesesario esto cuando tenemos que definir la variable afuera de
//un bloque de codigo para poder usarla mas adelante.

    }
}


Tiene que copiar cada clase a un archivo con su mismo nombre y eso lo compilan todo (si usan un projecto no van a tener problemas) sino van a tener que empezar a compilar desde la mas abstracta hasta la mas concreta. luego veran que se arma un .class que tiene el main y una carpeta "Geometria" que es el package.


Si bien ese codigo es funcional y pueden testearlo faltan algunas cosas como por ejemplo triangulo, me canse de hacerlo, asi que si no lo hicieron es tiempo de que practiquen y agregen ahi un triangulo.

Tampoco digo que sea la solucion perfecta al problema pero es mas o menos para que se den una idea de como se relacionan todos los conceptos que se venian viendo hasta ahora.

Faltaron algunos importantes como el de interface, pero si tengo tiempo, ganas y algun ejemplo ya lo estare agregando.

Estaria bueno que juegen un poco con este codigo (o con el que ya tienen hecho ustedes) y agregen por ejemplo la opcion de calcular perimetro, o agregen alguna figura mas, como rombo y esas cosas.

Saludos
« Última modificación: Abril 20, 2012, 06:51:40 pm por WaesWaes »

Desconectado WaesWaes

  • Actualmente es
  • Colaborador
  • ****
  • Mensajes: 4402
  • You are not prepared!
    • Ver Perfil
Re:JAVA desde CERO
« Respuesta #29 en: Abril 19, 2012, 08:59:45 am »
Clonacion

Cuando hablamos de clonacion nos referimos a la clonacion de objetos, en Java todavia no es posible clonar humanos (?)

Como los objetos siempre son pasados por referencia, si queremos modificar un objeto para hacer alguna especie de calculo o prueba, perdemos el estado del objeto inicial, en caso de que queramos almacenar una copia identica de un objeto en un instante dado tenemos que usar esta tecnica.

La clase java.lang.Object que es la padre de todas las clases de la API de Java contiene un metodo clone() que conoce la cantidad de memoria que ocupa un objeto en el sistema y es capaz de copiar identicamente esa memoria a otro lugar.
Para poder hacer un objeto clonable hay que hacer dos cosas, primero hay que indicar explicitamente que el objeto tiene permiso de ser clonado, para esto tenemos que implementar la interfaz Cloneable que no tiene ningun metodo asi que no hay que implementar nada de esta interfaz, solo sirve como un permiso.

Lo otro que hay que hacer es sobreescribir el metodo clone() de la clase java.lang.Object, de forma publica, y ahi definir como es que se clona nuestro objeto.

Vamos a ver como se hace esto:

Código: (java) You are not allowed to view links. Register or Login
public class Clase() implements Cloneable {
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        }
        catch(CloneNotSupportedException e) {
            // Aca se entra si no se implementa Cloneable
        }
        return clone;
    }
}

Como pueden ver creamos un Object llamamos a clone() de la clase Object que devuelve un Object y retornamos eso.

Esa es una clase media sin sentido porque solo se puede clonar y no tiene nada mas, supongamos esta clase:

Código: (java) You are not allowed to view links. Register or Login
public class Clase implements Cloneable {
   
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        }
        catch(CloneNotSupportedException e) {}
        return clone;
    }

    private String s;
 
    public String getString() {
       return s;
    }
 
    public void setString(String s) {
       this.s = s;
    }
}

El main para esa clase puede ser algo de este estilo:

Código: (java) You are not allowed to view links. Register or Login
public class Main{
public static void main(String [] args){
Clase c = new Clase();
c.setString("Hola");
System.out.println(c.getString());
Clase a = (Clase) c.clone(); //como clone() devuelve un Object hay que castear a Clase
System.out.println(a.getString());
}
}

Lo que acabamos de ver se conoce como shallow clone, y simplemente se clona la clase, pero esto puede ser no deseado porque una clase puede estar compuesta de objetos que son instancias de otras clases (por ejemplo: String), estas otras clases seguramente tambien tengan una forma de ser clonadas, entonces, para que la clonacion sea todo un exito hay que hacer lo que se conoce como deep clone.

Que pasa si no la hago?, puede que no copies un objeto sino una referencia a el (una flechita que apunta a donde esta) y entonces cuando tenes un clon este apunta con una "flecha" clonada AL MISMO objeto que el otro, entonces en realidad no se clono nada.

Para hacer un deep clone hay que buscar todos los objetos dentro de la clase y clonarlos a mano:

Código: (java) You are not allowed to view links. Register or Login
class Clase implements Cloneable {
   
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        }
        catch(CloneNotSupportedException e) {}
        //es la variable clone, con un cast a esta clase
        ((Clase)clone).setString(new String(s)); //se llama al metodo setString del clon
        //y se le asigna una nueva instancia del string
       
        return clone;
    }

    private String s;
 
    public String getString() {
       return s;
    }
 
    public void setString(String s) {
       this.s = s;
    }
}

Hay algunas otras clases que tienen su propio metodo clone() incluso pueden ser otras nuestras, vemos un ejemplo con uan clase dela API que se llama Vector.

Código: (java) You are not allowed to view links. Register or Login
class Clase implements Cloneable {
   
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        }
        catch(CloneNotSupportedException e) {}
        ((Clase)clone).setVector((Vector)v.clone()); //se llama al clone() de Vector
       
        return clone;
    }

     private Vector v;
 
    public Vector getThings() {
       return v;
    }
 
    public void setVector(Vector v) {
       this.v = v;
    }
}

Dejando de lado para que sirve Vector que se vera mas adelante.

Tambien puede que no queramos que se clone nuestra clase, por varias razones, uno pensara que no hay que implementar Cloneable para que este pase y listo, pero la mejor opcion es hacer un mecanismo para avisar a quien intente clonar la clase que no se puede clonar, osea, hacer algo lindo no algo que tire errores. la forma es esta:

Código: (java) You are not allowed to view links. Register or Login
final class Clase implements Cloneable {
   
    public Object clone() throws CloneNotSupportedException {
         throw new CloneNotSupportedException();
    }

    private String s;
 
    public String getString() {
       return s;
    }
 
    public void setString(String s) {
       this.s = s;
    }
}

public class Main{
public static void main(String [] args){
Clase c = new Clase();
c.setString("Hola");
try {
Clase a = (Clase) c.clone();
System.out.println(a.getString());
} catch(CloneNotSupportedException err) {
System.out.println("No me podes clonar");
}

}
}


Fijense que la clase de arriba es final para que no se puedan hacer hijas que sobreescriban el metodo y si se pueda clonar, y ahora lo que hicimos fue en el metodo clone(), pusimos una especie de mensaje que indica que no es clonable.
Por el momento si lo quieren usar usenlo asi como esta, ma adelante veremos que significa todo eso.

Si alguien ya sabe algun otro lenguaje esto es similar al constructor por copia, o ese constructor que hacian para crear un objeto a partir de otro de mismo tipo, solo que en Java se usa esta tecnica.



foreach y varargs


Esto no tiene nada que ver con lo que se venia viendo pero lo queria comentar para que programen un poco mejor o para que entiendan algunos codigos, y se trata de una forma de pasar parametros algo extraña y de un for con un comportamiento diferente al comun.

Que pasa queremos hacer un metodo que reciba una cantidad variable de parametros de un mismo tipo? usualmente usariamos un arreglo para eso, pero Java nos de la posibilidad de hacer algo de este tipo:

Código: (java) You are not allowed to view links. Register or Login
class asd {

public int sumar(int... numeros) {
             System.out.println(numeros[2]); //mostraria un 3 (acordarse que empieza en 0)
}

public asd() {
int suma = sumar(1,2,3,4,5,6);
System.out.println(resultado);
}

public static void main(String args[]) {
new asd();
}
}

Ven como se usa, no importa la cantidad de numeros que pases igual los recibe...es como un arreglo implicito.

Y otra cosa que esta muy buena es el for este (que en otros lenguajes se conoce como foreach).

Código: (java) You are not allowed to view links. Register or Login
class asd {

public int sumar(int... numeros) {
int resultado = 0;
for(int i : numeros) {
resultado += i;
}
return resultado;
}

public asd() {
int suma = sumar(1,2,3,4,5,6);
System.out.println(suma);
}
        //uso de varargs en el main
public static void main(String... args) {
new asd();
}
}

Que significa? mas o menos ustedes definen un tipo (int) y una nombre con el que van a hacer una referencia y luego ponen : seguido de la colecion que van a recorrer (todavia no conocemos ninguna coleccion, ya lo haremos) en este caso se pone el nombre que tiene "el arreglo" con los parametros

Saludos
« Última modificación: Abril 21, 2012, 08:43:15 am por WaesWaes »


xx
JAVA desde cero

Iniciado por vVegeta

73 Respuestas
22716 Vistas
Último mensaje ſeptiembre 08, 2008, 04:28:32 pm
por WaesWaes
xx
PHP desde cero***

Iniciado por buenasbikes

1 Respuestas
2012 Vistas
Último mensaje Noviembre 25, 2006, 07:13:42 pm
por ||Ray||
xx
Desde Cero

Iniciado por alzala

16 Respuestas
6285 Vistas
Último mensaje ſeptiembre 24, 2007, 06:51:02 am
por TXS
xx
Esteganografía Desde Cero.

Iniciado por Xionex

6 Respuestas
3704 Vistas
Último mensaje Agosto 12, 2009, 10:00:06 am
por Xionex
xx
Crackeo desde cero

Iniciado por maximunspider

14 Respuestas
19364 Vistas
Último mensaje Mayo 17, 2011, 06:08:11 am
por jep
exclamation
Empezar PHP desde CERO

Iniciado por tabi1

7 Respuestas
2428 Vistas
Último mensaje Agosto 21, 2012, 03:54:00 pm
por comcom.com
exclamation
Aprendiendo H++ desde cero...

Iniciado por Sthefano02

2 Respuestas
1508 Vistas
Último mensaje Octubre 07, 2010, 02:48:00 pm
por Sthefano02
xx
Desde CEro En linux

Iniciado por teufelkrieg

1 Respuestas
1342 Vistas
Último mensaje Enero 03, 2007, 06:29:44 pm
por rafaelsk
xx
XHTML - desde Cero

Iniciado por an7rax

0 Respuestas
1617 Vistas
Último mensaje Mayo 22, 2009, 05:10:21 pm
por an7rax
resuelto
Taller de CSS Aprendiendo desde Cero

Iniciado por carlmycol

28 Respuestas
22510 Vistas
Último mensaje Abril 15, 2013, 08:34:59 pm
por lfacul