AOWS

Just another adrian’s weblog

Sobreescribir métodos estáticos en Java

with 5 comments

Menudo título más puñetero para este post… y es que los métodos estáticos no se pueden sobreescribir en Java, en realidad se ocultan. Aunque esta cuestión es algo compleja.

Empecemos con los ejemplos:

class A {
    static void method1() {
        System.out.println("method1 from A");
    }
}

class B extends A {
    static void method1() {
        System.out.println("method1 from B");
    }
}

Si ahora creamos instancias de cada una de estas clases, vemos como parece que el método de B sobreescribe a A:

A a = new A();
a.method1(); // imprime "method1 from A"

B b = new B();
b.method1(); // imprime "method1 from B"

Pero la gran y enorme diferencia entre sobreescribir y ocultar sale a la luz cuando queremos hacer uso del polimorfismo:

void someMethod(A a) {
    a.method1();
}

// ...

B b = new B();
someMethod(b); // imprime "method1 from A"

Si el método estuviera realmente redefinido por B, entonces el código anterior debería imprimir "method1 from B". Pero como vemos esto no ocurre…

Lo que realmente está pasando guarda relación con el “fallo” de diseño de Java en el acceso a los miembros estáticos. La llamada a method1 se hace sobre el tipo sin importar si la variable tiene una referencia a una instancia o no ni de qué tipo sea ésta. Y someMethod sólo sabe que la variable es de tipo A, por lo que se ejecuta el método estático de esta clase.

Este tipo de llamadas deberían hacerse siempre sobre la clase y no sobre una instancia:

void someMethod(A a) {
    // a.method1(); <- NO
    A.method1();
}
&#91;/sourcecode&#93;

Por otra parte, si queremos acceder al <code>method1</code> de <code>A</code> desde <code>B</code> tenemos dos opciones, la primera la acabamos de ver y la segunda es utilizando <code>super</code> (desde un método no estático, claro):


class B extends A {
    static void method1() {
        A.method1(); // imprime "method1 from A"
        super.method1(); // error! no se puede acceder desde un método estático
        method1(); // ups, bucle infinito!
    }
    void method2() {
        A.method1(); // imprime "method1 from A"
        super.method1(); // imprime "method1 from A"
        method1(); // imprime "method1 from B"
    }
}

Ya por último un par de notas. Un método de instancia no puede sobreescribir ni ocultar a otro estático, y viceversa un método de clase no puede sobreescribir ni ocultar a otro de instancia. Cualquiera de estas situaciones se traduce en un error de compilación.

¿Enrevesado? Pues acabamos de empezar… welcome to Java world!

Written by adrian

21 mayo, 2009 a 20:46

Publicado en Uncategorized

5 comentarios

Subscribe to comments with RSS.

  1. Como te veo interesado en el mundo java, habla de un pool de objectos hecho a través de commons pool, anda😉. Por cierto los metodos static en Java son inmutables.

    Jorge

    1 junio, 2009 at 15:31

  2. AMIGO CREO QUE ESTAS CONFUNDIENDO A LA GENTE: me explico.
    en someMethod(A a) le estas diciendo que le pasas un objeto tipo A por eso usa el method1() de A, asi de simple, si pones someMethos(B b) te usara el de B.
    por favor no confundais a la gente.

    mjerez

    10 diciembre, 2010 at 17:19

  3. No, mjerez. En someMethod(A a) le estamos pasando un objeto de tipo B, y aún así usa el de A. Échale otro vistazo y lo entenderás.

    Un saludo.

    adrian

    10 marzo, 2011 at 12:57

  4. Tu post deja la carencia de lectura en tu persona es obvio porque la clase siempre tendrá su métodos originales. cuando heredas métodos publico o protected es una copia del mismo jamas el original ya que por algo se llama herencia si tu cambias el método en la clase hija es en la hija no afectaras a tu clase padre. por lo mismo cuando creas un objeto padre saca en salida su método pero tu en la hija lo sobreescribes pero el objeto de la clase padre esta en otro lugar y el objeto hijo en otro cada quien tiene copias de los métodos de su clase tu heredas de mi los rasgos pero si tu quieres cambiarlos con un cirujano tu cambiaras no yo jojo

    Ellot

    27 octubre, 2011 at 07:22

  5. Tu post deja la carencia de lectura en tu persona es obvio porque la clase siempre tendrá su métodos originales. cuando heredas métodos publico o protected es una copia del mismo jamas el original ya que por algo se llama herencia si tu cambias el método en la clase hija es en la hija no afectaras a tu clase padre. por lo mismo cuando creas un objeto padre saca en salida su método pero tu en la hija lo sobreescribes pero el objeto de la clase padre esta en otro lugar y el objeto hijo en otro cada quien tiene copias de los métodos de su clase tu heredas de mi los rasgos pero si tu quieres cambiarlos con un cirujano tu cambiaras no yo jojo

    Elliot Garcia Gnp

    27 octubre, 2011 at 07:23


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: