Sobrescritura de métodos en Java (Overriding)

Cada vez que se tiene una clase que hereda un método de una superclase, se tiene la oportunidad de sobreescribir el método (a menos que dicho método esté marcado como final). El beneficio clave al sobreescribir un método heredado es la habilidad de definir un comportamiento específico para los objetos de la subclase.Veamos un ejemplo de la sobreescritura de un método heredado:

public class Animal {

public void comer(){
System.out.println("Animal comiendo...");
}
}

class Caballo extends Animal{
public void comer(){
System.out.println("Caballo comiendo...");
}
}


Al momento de que Caballo hereda de la clase Animal obtiene el método comer() definido en Animal, sin embargo, se desea especificar un poco más el comportamiento de Caballo al momento de llamar a comer(), por lo tanto se define un método con el mismo nombre dentro de la clase Caballo. Debido a que ambos métodos tienen el mismo nombre, para saber qué método se invocará en tiempo de ejecución es necesario saber a qué objeto se está refiriendo. P. ej.:

public static void main(String... args){
Animal a = new Animal();
Caballo c = new Caballo();
a.comer();
c.comer();
}



Al ejecutar el código anterior obtenemos lo siguiente:

Animal comiendo...
Caballo comiendo...


Ahora en su versión polimórfica:

public static void main(String... args){
Animal a = new Caballo();
Caballo c = new Caballo();
a.comer();
c.comer();
}

Obtenemos lo siguiente:

Caballo comiendo...
Caballo comiendo...


En la primera ejecución del método tenemos una referencia a un Animal pero el objeto es un Caballo, por lo tanto, el método invocado es la versión definida en la clase Caballo. Es importante mencionar que al momento de invocar un método sobre una referencia Animal en un objeto Caballo solamente se podrá ejecutar el métodos si la clase Animal lo define, p. ej.:

class Animal {

public void comer(){
System.out.println("Animal comiendo...");
}
}

class Caballo extends Animal{
public void comer(){
System.out.println("Caballo comiendo...");
}
public void relinchar(){
System.out.println("Caballo relinchando...");
}
}

class ProbarMetodos{

public static void main(String... args){
Animal a = new Caballo();
Caballo c = new Caballo();
a.comer();
c.comer();
a.relinchar();
//error!
}
}


Aún cuando la clase Caballo define un método llamado relinchar(), la clase Animal no sabe que dicho método existe, por lo tanto, el compilador arrojará un error cuando se intente invocar al método relinchar() desde una referencia Animal, no importa que el objeto Caballo sí lo tenga.

Reglas para sobreescribir un método::

Las reglas básicas para la sobreescritura de métodos son las siguientes:

+ La lista de argumentos del método debe ser exactamente la misma.
+ El tipo de retorno debe de ser el mismo o un subtipo del tipo de retorno declarado originalmente.
+ El nivel de acceso no debe de ser más restrictivo.
+ El nivel de acceso puede ser menos restrictivo.
+ Los métodos de instancia pueden ser sobreescritos solamente si han sido heredados por la subclase.
+ Los métodos sobreescritos pueden arrojar cualquier excepción no verificada(de tiempo de ejecución) por el compilador.
+ Los métodos sobreescritos NO pueden arrojar excepciones verificadas por el compilador.
+ No se puede sobreescibir un método marcado como final.
+ No se puede sobreescibir un método marcado como estático (static).
+ Si un método no puede ser heredado, no puede ser sobreescrito.

Invocar la versión de la superclase de un método sobreescrito::

En algunas ocasiones necesitamos invocar al método escrito en la superclase en lugar de la versión que hemos sobreescrito, para ello se utiliza la palabra super seguida de un punto(.) y posteriormente el nombre del método a invocar, p. ej.:

class Caballo extends Animal{
public void comer(){
super.comer();
}
}


Hasta aquí llegamos con este tema. ¿Alguna duda? deja tu comentario.

Más sobre programación en Java aquí.

24 comentarios:

  1. Anónimo dijo...:

    Excelente es la segunda vez que miro y siempre es util a favoritos gracias!

  1. Monillo007 dijo...:

    Gracias por tus comentarios. Saludox

  1. Anónimo dijo...:

    Ohhhhhhhhh!! Genialísimo!!
    Me has salvado la vida!
    Has logrado lo que mi profe no pudo *-*
    Logré entender!

  1. Monillo007 dijo...:

    Mission Acomplished: Jajajajaja, gracias por tu comentario. Saludox.

  1. Anónimo dijo...:

    Gracias por la explicación. Estoy aprendiendo a programar en Java y tenía dudas sobre a que se referia el termino "Override", quedó aclarado.

  1. Anónimo dijo...:

    Gracias...muy claro

  1. Claudia dijo...:

    interesante la ayuda, pero podrias poner un ejemplo mas donde expliques paso por paso, donde no solo expliques acepciones sino tambien se vea detalladamente toda la rutina que hay que hacer para llegar a un resultado final. Me gustaria que fueraa asi.

  1. Monillo007 dijo...:

    Claudia,
    Me gustaría que fueras más específica ya que, de acuerdo a mi punto de vista, la explicación que hago es paso a paso e intento explicar cuestiones generales en la sobreescritura de métodos. ¿Cuál es tu duda particular?

  1. Anónimo dijo...:

    CUAL ES LA PALABRA CLAVE QUE PERMITE SOBRESCRIBIR UN METODO HEREDADO?

  1. Anónimo dijo...:

    saben la verdad yo noy experto y debo comentar que estoy aprendiendo, a programar ahce poco, pero puedo comentar que la forma de comentar o de explicar el funcionamiento de una clase, metodo, arreglo etc me ha gustado muchisimo seguire buscando en este portal ejemplos, un usuario que queda mu agradecido de este portal

  1. Willy dijo...:

    Añadir un último caso, utilizando super en la clase derivada y fuera:

    class Animal {

    public void comer(){
    System.out.println("Animal comiendo...");
    }
    }
    class Caballo extends Animal{
    public void comer(){
    System.out.println("Caballo comiendo...");
    }

    public void usoSuper(){
    System.out.println(super.comer());
    }
    }

    public static void main(String... args){
    Animal a = new Animal();
    Animal b = new Caballo(); //Solo en este sentido
    Caballo c = new Caballo();
    a.comer();
    b.comer(); //Causa Overriding mostrando el de la derivada
    b.super.comer(); //Es afectado por el Overriding pero utilizando super accedemos al metodo de la classe de la cual hereda.
    c.usoSuper();
    }

    En este caso veríamos:

    Animal comiendo... //evidente
    Caballo comiendo... //sin utiliza super vemos la el metodo de la classe derivada
    Animal comiendo... //usando super
    Animal comiendo... //otro método encapsulando comer

    Espero que a alguien le pueda ser útil :)

  1. Anónimo dijo...:

    perfecto!!

  1. Anónimo dijo...:

    La Regla: "Los métodos sobreescritos NO pueden arrojar excepciones verificadas por el compilador".

    Quisiera matizar que:

    Precisamente el metodo que se sobreescribe (el super metodo o sobreescrito) es que que puede. El que no puede arrojar una excepcion verificada es el metodo que sobreescribe al super. Sin embargo puede arrojar menos excepciones que el super o bien una excepcion subclase de la que arroja el super.

  1. Andrés dijo...:

    Gracias por tus comentarios. Te hago una pregunta de algo que no me queda del todo claro.

    Cuando hacés:

    public static void main(String... args){
    Animal a = new Caballo();
    Caballo c = new Caballo();
    a.comer();
    c.comer();
    }

    Obtenés:

    Animal comiendo...
    Caballo comiendo..

    Pero cuando hacés:

    class Animal {

    public void comer(){
    System.out.println("Animal comiendo...");
    }
    }

    class Caballo extends Animal{
    public void comer(){
    System.out.println("Caballo comiendo...");
    }
    public void relinchar(){
    System.out.println("Caballo relinchando...");
    }
    }

    class ProbarMetodos{

    public static void main(String... args){
    Animal a = new Caballo();
    Caballo c = new Caballo();
    a.comer();
    c.comer();
    a.relinchar(); //error!
    }
    }

    relinchar() tira en un error. ¿Por qué? Si por más que la referencia es un Animal el objeto es un Caballo, ¿no debería funcionar?
    Para mí si en el primer ejemplo 'a.comer()' devuelve "Caballo comiendo", en el segundo 'a.relinchar()' tendría que andar.

  1. Anónimo dijo...:

    Perfecto me saco de un gran apuro entendi mas rapido aqui que en la clase del profesor saludos.

  1. Jeyson dijo...:

    EXELENTE compadre entendi de maravilla saludos gracias. sigue posteando cosas de java (matrices y cosas asi )

  1. Anónimo dijo...:

    Exactamente lo que buscaba ;-) gracias

  1. Anónimo dijo...:

    buen articulo , pero hubiese sido mejor utilizar datos de la vida real para entender mejor su funcionalidad y donde usarlo , ejemplo con datos sistema banco...algo pequeño

  1. Omar dijo...:

    Excelente la explicación

  1. Anónimo dijo...:

    Que buena explicación, no encontré nada parecido por ahí, muchas gracias, sigue así.

  1. Anónimo dijo...:

    Buena mi negro, buena. Solo he visto dos de tus trabajos pero geniales. Buena onda :)

  1. Anónimo dijo...:

    No hay nada mas simple para entender este tema en java gracias Monillo007

  1. Jesus Gomez dijo...:

    Muchas gracias por tu trabajo ! realmente se aprecia! sigue asi!

  1. Anónimo dijo...:

    Muchisimas gracias :)

Publicar un comentario

Este es un espacio abierto, puedes escribir lo que gustes respetando los siguientes puntos:

1.- Lo que escribas esté relacionado con el post, si gustas contactarme puedes hacerlo aqui.

2.- Todo es cuestionable, aunque ten en cuenta que existen formas de hacerlo, evita las agresiones y revisa tu lenguaje antes de publicar un comentario.

3.- Siempre hay tres verdades: tu verdad, mi verdad y la verdad, por lo que opiniones diferentes no necesariamente son equivocadas.

4.- Los comentarios son una forma de discusión abierta, por lo que al publicar uno, implícitamente entras a una discusión, con todo lo que esto representa.

5. Me reservo el derecho de eliminar comentarios que no respeten las condiciones mencionadas anteriormente.

Toma en cuenta que puedes utilizar emoticones en tu comentario, para ver una lista de los disponibles da clic en este enlace.

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