Autor Tema: Ejercicio CU00683B Métodos de Clase/de Instancia java  (Leído 5422 veces)

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Ejercicio CU00683B Métodos de Clase/de Instancia java
« en: 02 de Agosto 2014, 09:06 »
Hola. Esta es mi respuesta al enunciado del ejercicio.

El error dado, es: Cita 1
Citar
Non-static variable this cannot be referenced from a static context

Que la variable o método no es estático y no puede referenciarse desde un contexto estático (el main)


¿Por qué lo da?: Cita 2
Citar
a) No pueden acceder a campos de instancia (lógico, pues los campos van asociados a objetos).
b) No pueden invocar a un método de instancia de la misma clase (lógico pues los métodos de instancia van asociados a objetos).


Solución:
Cambiando el método 'getAtrib1()' a estático, también es necesario cambiar a estático el atributo de la clase 'atributo1'. Y dentro del main hay que quitar el 'this' de la llamada getAtrib1()

Estos cambios los he hecho después que el compilador me diera error en cada uno de estos nombres. Y serán razones lógicas para el compilador, pero para mí están ocultas.
Pues, si no se puede (ver Cita 2), ¿como es que después de añadir 'static' se si puede acceder a campos y métodos de la instancia?

Entiendo más el porqué, viendo el ERROR (ver Cita 1) que da el compilador, si hacemos los atributos y métodos estáticos se podrán llamar desde el main (estático).
Es como si al ser todos estáticos, se pudieran comunicar entre ellos.

Saludos.
« Última modificación: 31 de Agosto 2014, 11:04 por Alex Rodríguez »

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio CU00683B Métodos de Clase/de Instancia
« Respuesta #1 en: 02 de Agosto 2014, 14:27 »
Voy a intentar explicarte el porque de esas razones que según tu están ocultas, jeje.

Método estático

A ver normalmente un método estático es un método, el cual no requiere de la creación de un objeto para poder invocarlo, a grosso modo, son métodos que recibirán una serie de datos y devolverán un resultado, pero como hemos comentado no es necesario crear un objeto para invocar a dicho método, por tanto al no crear ningún objeto, los atributos no están inicializados.

Lo mismo ocurre con los métodos que no son estáticos, estos métodos solo existen cuando se crea un objeto y es a través de ese objeto sobre el que llamamos a los métodos. Cuando llamamos a un método estático, no es necesario crear un objeto, y por tanto esos métodos no estáticos no existen, con lo cual no pueden ser llamados, que es lo que ocurre en este ejercicio.

Cuando llamamos a un método estático de una clase, solo existirán los atributos y métodos que sean estáticos. Con lo cual este ejercicio podría tener dos posible soluciones:

Una, la que tu has echo, que es declarar los elementos que se usan dentro de un método estático como estáticos lo cual genera una cadena, ya que al convertir el método  getAtrib1() a estático, este hace una llamada al atributo1 el cual para poder usarlo dentro de un método estatico( el que acabamos de convertir ), el atributo también debe ser estático, por lo cual también es necesario realizar ese cambio y convertir el atributo1 a estático.

Bien, esta bien echo y dado que el objetivo del ejercicio es aprender el uso de la palabra reservada static es la forma correcta de actuar.

Otra posible solución podría haber sido simplemente crear un objeto de la clase Test y sustituir la palabra reservada this por el nombre que le hubieras dado al objeto. Aunque claro de este modo no verías como se produce un método estático que hace uso de atributos estáticos dentro de la misma clase.

Resumiendo lo que debes saber es que para poder usar un atributo o un método de una clase dentro de un método estático de la misma clase, dos posibilidades:

  • Establecer los atributos y métodos también como estáticos
  • O crear un objeto de esa clase y a través de este ya puedes llamar a los métodos y atributos
   

Bueno espero no haberte liado mucho y haberte aclarado alguna que otra cosilla, de todas formas es lo de siempre práctica, práctica y mas práctica... Un saludo!

       
 

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio CU00683B Métodos de Clase/de Instancia
« Respuesta #2 en: 03 de Agosto 2014, 08:23 »
Hola dongo. Gracias por tus comentarios.

Entiendo parte de lo que dices. Lo que no entiendo es:
Citar
Establecer los atributos y métodos también como estáticos
O crear un objeto de esa clase y a través de este ya puedes llamar a los métodos y atributos
El segundo párrafo, lo de crear un objeto de esa clase.
He intentado crear ese objeto de la clase Test y todo lo que hago me da error.
No puedo crearlo dentro del main de Test
En una clase nueva intento crear un objeto de la clase Test y también me da error.
No sé como crear ese objeto de la clase Test.

¿Puedes mostrarme un ejemplo?

Salud y gracias.

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio CU00683B Métodos de Clase/de Instancia
« Respuesta #3 en: 03 de Agosto 2014, 12:09 »
jeje Hola buenos días, bueno veamos, el ejercicio original es el siguiente:

Código: [Seleccionar]
public class Test {
 int atributo1;
 Test (int atrib) {atributo1 = 0;}
 public static void main (String[ ] Args) {
 System.out.println ("Mensaje 1");
 System.out.println ("Atributo 1 vale" + this.getAtrib1());
 } //Cierre del main
 public int getAtrib1() {return atributo1;}
} //Cierre de la clase

Como tu bien comentas en el primer post el error viene dado en esta linea:

Código: [Seleccionar]
System.out.println ("Atributo 1 vale" + this.getAtrib1());

Donde se intenta llamar al método getAtrib1() en un contexto estático (método main es estático) cuando el método resulta que no es estático, la clave esta en la palabra reservada this, digamos que de alguna manera this se sustituye en este caso por la palabra Test, con lo cual, la linea que nos esta generando el error es equivalente a la siguiente:

Código: [Seleccionar]
System.out.println ("Atributo 1 vale" + Test.getAtrib1());

Si ahondamos el la teoría, nombre_de_clase.nombre_metodo() --> Es la forma de llamar a un método que es estático dentro de la clase, pero en este caso resulta que getAtrib1() no es un método estático y por tanto el compilador como tu bien dices:

Citar
Non-static variable this cannot be referenced from a static context

Así que te comentaba que había dos soluciones, una ya la sabemos que es convertir tanto el método getAtrib1() como la propiedad atributo1 a estáticos.

La otra solución que te comentaba es crear un objeto, Pues simplemente es añadir una linea nueva dentro del main con la creación de un objeto de tipo Test y cambiar la palabra reservada this por el nombre que le hemos dado al objeto, con lo que el código quedaría de la siguiente forma:

Código: [Seleccionar]
public class Test {
    int atributo1;
    Test (int atrib) {atributo1 = 0;}
    public static void main (String[ ] Args) {
        Test t=new Test(5);
        System.out.println ("Mensaje 1");
        System.out.println ("Atributo 1 vale" + t.getAtrib1());
    } //Cierre del main
    public int getAtrib1() {return atributo1;}
} //Cierre de la clase

Si te fijas lo que hago es crear e inicializar un objeto llamado t y después en lugar de llamar al método directamente

Código: [Seleccionar]
this.getAtrib1()
Lo llamaríamos a través del objeto t que acabamos de crear de la siguiente forma:

 
Código: [Seleccionar]
t.getAtrib1()
Con lo cual la llamada al método ya no se hace de forma estática (Test.getAtrib1())
sino que lo hacemos a través de un objeto inicializado llamado t (t.getAtrib1())

No te preocupes si no entiendes muy bien cuando hacer una cosa o cuando hacer otra, con la practica te irás dando cuenta poco a poco.

Para ponerte un ejemplo, la clase java.lang.Math es una clase donde todos sus métodos no estáticos.

http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html

Resumiendo un poco:
Yo me quedaría con lo siguiente, en un método estático no es posible llamar a  métodos no estáticos de la misma clase ni a propiedades que tampoco sean estáticas dentro de la misma clase.

Pero ya te digo, no te preocupes porque poco a poco te irás dando cuenta de como actuar según lo que se te presente.

 Un saludo y siento estas extensiones de post...

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio CU00683B Métodos de Clase/de Instancia
« Respuesta #4 en: 04 de Agosto 2014, 06:59 »
Hola dongo.
En primer lugar, gracias por tu post, y sobre todo por su extensión. No se desaprovecha nada. No se si es así, pero me parece que escribes como hablas.
Lo dices de una forma llana sin demasiados tencnicismos que es fácil de entender.

Ahora si he pillado el asunto. (crear un objeto dentro del main)
La verdad, una vez lo ves te parace fácil. Como no se me ha ocurrido a mi.

Cada vez que me dais una lección en el foro, me doy cuenta de las cosas que no veía, los rincones que no me olía...
En fin que sois una buena escuela. :)

Salud y gracias.

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".