Orientación a Objetos (Object Orientation) II - Sobrescritura de métodos
viernes, noviembre 11, 2011 at 3:35PM
gishac in certificacion, certificacion, java, java, ocjp, ocjp, ocp, ocp, ocpjp, orientacion a objetos, scjp, scjp

Continuando con la revisión de todos los conceptos necesarios de orientación a objetos en Java para aplicarlos no sólo en dar el examen de certificación sino en el diario vivir empezamos con los siguientes temas relacionados (El post precedente de éste tema lo encuentras acá)

Overriding (Sobrescritura de métodos)
Cuando haces uso de herencia tienes la posibilidad de sobrescribir los métodos de la clase padre (si y solo si no están marcados como final); el uso de la sobrescritura es definir un comportamiento particular de un método en una subclase.

public class Animal {

	/**
	 * Metodo de la clase base
	 */
	public void doSound(){
		System.out.println("animal sound");
	}	
}

class Cat extends Animal {
	
	/**
	 * Metodo sobreescrito (override)
	 */
	@Override
	public void doSound() {
		System.out.println("meow");
	}	
		
}

Como se puede ver en el ejemplo anterior, la clase Cat hereda de Animal pero le da un comportamiento particular en el método doSound, lo cual es el objetivo del polimorfismo y la sobrescritura de métodos, que una subclase pueda definir un comportamiento propio.

Si ejecutamos el codigo

        public static void main(String[] args){
		new Cat().doSound();
	}

El resultado sera "meow" ya que el sobrescribir el método al momento de ejecutar el programa, la JVM ignora la implementacion de la superclase y ejecuta el método de la clase heredada que implementa su comportamiento propio.

Las reglas para la sobrescritura (overriding) de un método son las siguientes:

 

La sobrecarga de métodos es opcional, pero cuando heredamos de una clase abstracta ésta nos obliga a implementar todos sus métodos (Y aunque quizás no parezca sobrescritura, lo es), por lo cual podemos inferir que la implementación de una clase abstracta es tener uno o más métodos que deben sobrescritos si o si.

Ejecutando el metodo base

En algunos casos no queremos sobrescribir completamente lo que hace un método, sino mas bien agregar funcionalidad a lo que hace ya un método base, por lo que es necesario invocar el método de la superclase y luego agregar algo personalizado, para lograr este objetivo se hace a través de la palabra reservada super:

public class Animal {

	/**
	 * Metodo de la clase base
	 */
	public void doSound(){
		System.out.println("brrrr");
	}	
	
	public static void main(String[] args){
		new Cat().doSound();
	}	
}

class Cat extends Animal {
	
	/**
	 * Metodo sobrescrito (override)
	 */
	@Override
	public void doSound() {
		super.doSound();
		System.out.println("meow");
	}	
	
}

El resultado de ejecutar el código precedente es:
brrrr
meow

Para las preguntas de la certificación es importante recordar las reglas antes mencionadas para tener claras todas las variantes y no caer en las preguntas trampa del examen.

Preguntas típicas de examen respecto a esta materia.

 ¿Cuál sería la salida del siguiente programa?

package es.javahispano;

public class Animal {

    public String saluda() {
        return "Hola, ¡soy un animal!";
    }

    public static void main(String args[]) {
        Animal animal = new Animal();
        Gato gato = new Gato();
        Perro perro = new Perro();
        System.out.println(gato.saluda());
        System.out.println(perro.saluda());
        System.out.println(animal.saluda());
        System.out.println(((Animal)gato).saluda());
        System.out.println(((Animal)perro).saluda());        
    }

}

class Perro extends Animal {

    public String saluda() {
        return "Hola, ¡soy un perro!";
    }

}

class Gato extends Animal {

    public String saluda() {
        return "Hola, ¡soy un gato!";
    }
}

La respuesta es:

Hola, ¡soy un gato!
Hola, ¡soy un perro!
Hola, ¡soy un animal!
Hola, ¡soy un gato!
Hola, ¡soy un perro!

Porque en tiempo de ejecución, la JVM es capaz de conocer qué tipo de clase está en memoria en ese momento, y, consecuentemente, qué metodo llamar.

 Más cosas a tener en cuenta sobre preguntas relativas a esta cuestión

En esta parte, nos pueden caer preguntas como las siguientes:

Por ejemplo:

package sobreescritura;

public class Padre {

    private void hola(){
        System.out.println("Hola soy el padre");
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        Padre padre = new Padre();
        Hijo hijo = new Hijo();
        padre.hola();
        hijo.hola();
    }

}

class Hijo extends Padre{
    
    public void hola(){
        System.out.println("Hola soy el hijo");
    }
    
}

La pregunta es, ¿existe sobreescritura de métodos? La respuesta es que no, porque el método la clase hija no tiene noción del método de la clase padre, al ser este de caracter privado.

 

Article originally appeared on javaHispano (http://www.javahispano.org/).
See website for complete article licensing information.