Foro de elhacker.net

Programación => Java => Mensaje iniciado por: robertito_prado en 27 Julio 2013, 19:22 pm



Título: Duda con clases
Publicado por: robertito_prado en 27 Julio 2013, 19:22 pm
Hola!

Estoy haciendo un programa en Java y tengo dos clases en el mismo package. Mi duda es si con un objeto de la clase1, puedo llamar a un método de la clase2, porque lo necesito para acabar el programa. Yo probé pero me da fallo:

 Clase1 nombre=new Clase1();
 nombre.metodoClase2();

Un saludo y gracias de antemano.


Título: Re: Duda con clases
Publicado por: 1mpuls0 en 28 Julio 2013, 05:13 am
Para que puedas acceder a un metodo de la ClaseB desde la ClaseA el método de ClaseB debe ser public.

Saludos.



Título: Re: Duda con clases
Publicado por: Alien-Z en 28 Julio 2013, 07:12 am
Ha habido una confusión por parte de Darhius:

Solo podrás acceder a un método de ClaseB mediante un objeto de tipo ClaseB o sus subclases. No hay ninguna forma de crear un objeto de un tipo y usar funciones de otro tipo.

Lo que Darhius quiere decir es que dentro de un método de ClaseA puedes crear un objeto de ClaseB y usar sus funciones desde dicho objeto.

En definitiva: No es posible hacer algo así porque viola los principios de la programación orientada a objetos.

Como alternativa puedes declarar la función como un método de clase utilizando "static":

Código
  1. public static void funcion() {
  2. ...
  3. }

Esto te permitirá usar la función sin crear ningún objeto:

Código
  1. ClaseA.funcion(); //Fíjate que lo que hay antes del punto es el nombre de la clase, no un objeto

Un saludo.


Título: Re: Duda con clases
Publicado por: ~ Yoya ~ en 28 Julio 2013, 07:18 am
Para que puedas acceder a un metodo de la ClaseB desde la ClaseA el método de ClaseB debe ser public.

No necesariamente, si la clase se encuentra en el mismo paquete (como es el caso) puedes acceder a los metodos y variables miembros de la clase que no sean privados.

Si la clase1 es una subclase de la clase2, entonces puedes llamar los metodos de la clase2, siempre y cuando el tipo de referencia sea de la clase 2. Pero solo podras acceder a los metodos de la clase1 que sobre-escriban a los metodos de la clase2.

Código
  1. package ejemplo;
  2.  
  3.  
  4. class Clase1 extends Clase2{
  5.    public static void main(String[] args) {
  6.        Clase2 clases = new Clase1();//Creo una variable del tipo Clase2
  7.                                     //Luego un objeto de Clase1 y
  8.                                     //lo asigno a la variable clases
  9.  
  10.        clases.saludo();//Salida: "Clase2.....
  11.        //clase.hola() //Error, ya que solo puedo acceder a los metodos
  12.                       //de la clase 2 a excepcion de los metodos que la Clase1
  13.                       //sobre-escribe
  14.  
  15.  
  16.    }
  17.  
  18.    void hola() {
  19.        System.out.println("Hola mundo:P");
  20.    }
  21. }
  22.  
  23. class Clase2 {
  24.  
  25.    void saludo() {
  26.        System.out.println("Clase2.....");
  27.    }
  28.  
  29. }

Saludos.


Título: Re: Duda con clases
Publicado por: 1mpuls0 en 28 Julio 2013, 09:02 am
Cierto me confundí. Gracias.

Saludos.




Título: Re: Duda con clases
Publicado por: robertito_prado en 28 Julio 2013, 15:16 pm
Gracias! lo que hice fue extender una clase de la otra, así es su subclase...

Aunque lo unico que hice fue cambiar de error:  Exception in thread "main" java.lang.StackOverflowError

Saludos!


Título: Re: Duda con clases
Publicado por: Alien-Z en 28 Julio 2013, 19:51 pm
Facilitaría mucho las cosas que pusieras al menos la parte de código que te genera el error, sino resulta imposible.

Lo más que te puedo decir es que la excepcion "java.lang.StackOverflowError" salta por desbordamiento: Intentas acceder al elemento de un array que no existe, reservas memoria infinita, etc.

Saludos.


Título: Re: Duda con clases
Publicado por: robertito_prado en 29 Julio 2013, 15:58 pm
Hola!

Pues os voy a dejar el código a ver si me podeis ayudar... El error es de la pila, que se llena, debido a un bucle infinito (creo).
Lo que no se es porque tengo un bucle infinito:

package paquete;

    public class Carta extends Baraja{
      static String numero;
      static String palo;
   
    public Carta(String numero, String palo){
       this.numero=numero;
       this.palo=palo;
      
    }
    public static void main (String[] args){
      
       Carta miCarta = new Carta("Tres","Copas");
       Baraja miBaraja =new Baraja();
       System.out.print("La posicion de mi carta es: "+miCarta.posicionCarta(numero, palo));
    }
   
 }


package paquete;

public class Baraja{
       Carta[] paquete;
      public Baraja(){  //Genera todas las cartas
          String caras[] = { "As", "Dos", "Tres", "Cuatro", "Cinco", "Seis",
                          "Siete", "Sota", "Caballo", "Rey"};
          String palos[] = { "Bastos", "Copas", "Oros", "Espadas" };
          paquete = new Carta[40];
          for ( int i = 0; i < paquete.length; i++ ){
                   paquete = new Carta(caras[i%10],palos[i/10]);     --------------> Aqui es donde falla,
                                                                                                                                                    bucle infinito
          }
         
       }
       int posicionCarta(String n, String p){
          int posicion=0;
          for(int i=0; i<40; i++){
             if((paquete.numero==n) && (paquete.palo==p)){
                posicion=i;
             }
          }
          return posicion;
       }   
}


Título: Re: Duda con clases
Publicado por: ~ Yoya ~ en 29 Julio 2013, 19:12 pm
java.lang.StackOverflowError se lanza normalmente cuando hay métodos recursivos que se llaman infinitamente. Por lo tanto el llega un punto en que el Stack se va llenando y explota.

En la memoria Stack se almacenan las variables locales y llamadas a métodos. Aquí un pequeño ejemplo de como funciona la memoria Stack.

Código
  1. public static void main(String[] args) {
  2. int x = 5;
  3. saludo();
  4. }
  5.  
  6. void saludo() {
  7.  
  8. go()
  9. }
  10.  
  11.  

En la linea 2 el stack se puede visualizar asi.

main (metodo) - x (variable local)

Luego linea 3:

saludo() (metodo)
main (Metodo) - x (variable local)

Y asi se va llenando la memoria Stack, cuando el metodo saludo() se complete, entonce el metodo saludo() se remueve del stack y vuelve al metodo main, pero si el metodo saludo llama a otro metodo, este se agrega al Stack, y cuando ese otro metodo termine, se remueve del stack y luego vuelve al metodo saludo, y cuando saludo termine, se remueve del stack y vuelve al metodo main hasta que el metodo main se completa.


Te explico el error lógico que cometes, y por eso sale la excepción.

Las clases:
Código
  1. class Carta extends Baraja {}
  2. class Baraja {}

Tomando en cuenta que el loop for se encuentra en el constructor de la clase Baraja.

Tu metodo main:
Código
  1.    public static void main(String[] args) {
  2.  
  3.        Carta miCarta = new Carta("Tres", "Copas");
  4.        Baraja miBaraja = new Baraja();
  5.        System.out.print("La posicion de mi carta es: " + miCarta.posicionCarta(numero, palo));
  6.    }

En la linea 4(marcada), se instancia la Clase Baraja y se ejecuta el constructor de Baraja.

Baraja constructor:

Código
  1.    public Baraja() {  //Genera todas las cartas
  2.        String caras[] = {"As", "Dos", "Tres", "Cuatro", "Cinco", "Seis",
  3.            "Siete", "Sota", "Caballo", "Rey"};
  4.        String palos[] = {"Bastos", "Copas", "Oros", "Espadas"};
  5.        paquete = new Carta[40];
  6.        for (int i = 0; i < paquete.length; i++) {
  7.            paquete[i] = new Carta(caras[i % 10], palos[i / 10]);
  8.  
  9.        }
  10.  
  11.    }

El error se encuentra en la linea 7(marcada), la linea 7 Crea una instancia de la Clase Carta y como la clase Carta extiende a la Clase Baraja (Clase padre), entonce java primero llama al Constructor de la clase padre (En este caso Baraja) y lo ejecuta:

Baraja constructor:

Código
  1.    public Baraja() {  //Genera todas las cartas
  2.        String caras[] = {"As", "Dos", "Tres", "Cuatro", "Cinco", "Seis",
  3.            "Siete", "Sota", "Caballo", "Rey"};
  4.        String palos[] = {"Bastos", "Copas", "Oros", "Espadas"};
  5.        paquete = new Carta[40];
  6.        for (int i = 0; i < paquete.length; i++) {
  7.            paquete[i] = new Carta(caras[i % 10], palos[i / 10]);
  8.  
  9.        }
  10.  
  11.    }

Y en la linea 7, de nuevo hace una una instancia de la clase Carta y como esta extiende a la clase Baraja, se llama primero al constructor de la clase Baraja y se ejecuta, y pasa lo mismo que ahora. Entonce como sigue pasando lo mismo y ningun constructor de la clase Baraja se llega a completar sino que se van aumentando, la memoria Stack se va llenando ya que nunca los constructores no se llegan a ejecutar por completo y por lo tanto nunca se llegan a remover de la memoria Stack. Y por eso el código lanza la excepción java.lang.StackOverflowError

Por esa razón, se recomienda solo instanciar variable en constructores y no hacer llamada a métodos.

El bucle for y eso, déjaselo a un método y recuerda no llamar a ningún método desde el constructor....

Saludos.


Título: Re: Duda con clases
Publicado por: robertito_prado en 29 Julio 2013, 21:45 pm
Muchas gracias por la explicación, ahora caigo! Este error viene dado por intentar solventar otro error.. jeje

Esto: "miCarta.posicionCarta(numero, palo)" no me funcionaba y por eso extendi la clase carta de la clase baraja, para que los objetos de Carta pudieran usar los métodos de Baraja...

Saludos!


Título: Re: Duda con clases
Publicado por: robertito_prado en 1 Agosto 2013, 12:58 pm
package paquete;

    public class Carta{
        static String numero;
        static String palo;
   
    public Carta(String numero, String palo){
       this.numero=numero;
       this.palo=palo;
      
    }
    public static void main (String[] args){
      
       Carta miCarta = new Carta("Tres","Copas");
       Baraja miBaraja =new Baraja();
       System.out.print("La posicion de mi carta es: "+miCarta.posicionCarta(numero, palo)); -----> MARCADO
    }
   
 }


package paquete;

public class Baraja{
      Carta paquete[];
      public Baraja(){
          String caras[] = { "As", "Dos", "Tres", "Cuatro", "Cinco", "Seis",
                          "Siete", "Sota", "Caballo", "Rey"};
          String palos[] = { "Bastos", "Copas", "Oros", "Espadas" };
          paquete = new Carta[40];
          for ( int i = 0; i < paquete.length; i++ ){
                   paquete = new Carta(caras[i%10],palos[i/10]);
                   System.out.print(i);
          }
         
       }
       public int posicionCarta(String n, String p){
          int posicion=0;
          for(int i=0; i<40; i++){
             if((paquete.numero==n) && (paquete.palo==p)){
                posicion=i;
             }
          }
          return posicion;
       }   
}

perdonad pero esta duda me esta volviendo loco:

¿Por que no puedo hacer lo que está marcado?¿No se supone que si posicionCarta es public lo pueden usar clases que estén hasta en otro paquete? ¿Por que no lo puedo usar yo si mis clases están las dos en el mismo paquete?

Un saludo!


Título: Re: Duda con clases
Publicado por: 1mpuls0 en 1 Agosto 2013, 16:55 pm
perdonad pero esta duda me esta volviendo loco:

¿Por que no puedo hacer lo que está marcado?¿No se supone que si posicionCarta es public lo pueden usar clases que estén hasta en otro paquete? ¿Por que no lo puedo usar yo si mis clases están las dos en el mismo paquete?

Un saludo!

La que veo es que te falta el extends.

Saludos.


Título: Re: Duda con clases
Publicado por: robertito_prado en 1 Agosto 2013, 18:13 pm
Claro, pero debería ir sin el extends, porque es público el método y están en el mismo paquete...

Saludos!