2.4 Overriding Overloading - ajpaez/OCA GitHub Wiki

(OCA Objectives 6.1, 6.3,7.2, and 7.3)


Métodos sobrescritos

Cada vez que se hereda un método de una superclase, este se puede sobrescribir, si es necesario, para definir un comportamiento particular a la subclase. Para los métodos abstractos que heredan de una superclase, DEBE implementar el método a menos que la subclase sea abstracta también. Ejemplo de sobre escritura para el método eat de la superclase Animal en la subclase Horse:

public class TestAnimals {
  public static void main (String [] args) {
    Animal a = new Animal();
    Animal b = new Horse();  // Animal ref, but a Horse object
    a.eat(); // Runs the Animal version of eat()
    b.eat(); // Runs the Horse version of eat()
    a.buck();  // the compiler looks only at the reference type;
           // Animal class doesn't have that method
  }
}
class Animal {
  public void eat() {
    System.out.println("Generic Animal Eating Generically");
  }
}
class Horse extends Animal {
  public void eat() {
    System.out.println("Horse eating hay, oats, "
                       + "and horse treats");
   }
   public void buck() { }
}

Las reglas para la sobreescritura son:

  • La lista de argumentos debe coincidir exactamente con el método sobrescrito, sino será un método sobrecargado.
  • El valor devuelto debe ser del mismo tipo o de un subtipo del declarado en el método sobrescrito.
  • El nivel de acceso (modificador) NO puede ser MAS restrictivo que el del sobrescrito.
  • El nivel de acceso (modificador) SI puede ser MENOS restrictivo que el del sobrescrito.
  • Los métodos de instancia pueden ser sobrescritos solo si son heredados por una subclase. Una subclase dentro del mismo paquete que la superclase puede sobrescribir cualquier método de la superclase que no este marcado como private o final. Una subclase en un paquete diferente de la superclase puede solo sobrescribir los métodos public o protected, los final no.
  • Los métodos sobrescritos pueden lanzar cualquier excepción uncheked (tiempo de ejecución), independientemente de si el método al que sobrescribe declara la excepción.
  • Los métodos sobrescritos no pueden lanzar excepciones checked nuevas o mas genéricas que las declaradas en el método que sobrescriben.
  • Los métodos sobrescritos no tiene que declarar ninguna excepción que el nunca vaya a lanzar, independientemente de que el método que lo va a sobrescribir las declare.
  • NO se puede sobrescribir un método marcado como FINAL
  • NO se puede sobrescribir un método marcado como static.
  • Si un método no puede ser heredado no puede ser sobrescrito.

El método sobrescrito que se llamará, se decide en tiempo de ejecución según el tipo de objeto que lo llame.

public class TestAnimals {
  public static void main (String [] args) {
    Horse h =  new Horse();
    h.eat(); // Not legal because Horse didn't inherit eat()
  }
}
class Animal {
  private void eat() {
    System.out.println("Generic Animal Eating Generically");
  }
}
class Horse extends Animal { }

Invocar al método sobrescrito en la superclase.

Usando la palabra reservada super podemos invocar los métodos de instancia de la superclase. ##Ejemplos ilegales de métodos sobrescritos Respecto de la siguiente clase:

public class Animal {
  public void eat() { }
}
Método sobrescrito ilegal Problema
private void eat(){} Modificador de acceso mas restrictivo
public void eat() throws IOException{} Declara una excepción checked no definida por la superclase
public void eat(String food){} Método sobrecargado NO sobrescrito (argumentos distintos)
public String eat(){} No sobrescrito, cambia el tipo de dato devuelto, y no es sobrecargado porque no cambia la lista de argumentos

Métodos sobrecargados

Los métodos sobrecargados permiten rehusar el mismo nombre de método en una clase, pero con diferentes argumentos. Las reglas para los métodos sobrecargados son:

  • Deben cambiar la lista de argumentos
  • Pueden cambiar el tipo de retorno
  • Pueden cambiar el modificador de acceso.
  • Pueden declarar excepciones checked nuevas o mas genéricas.
  • Un método puede ser sobrecargado en la misma clase o en una subclase.

Sobrecargas legales

Según el siguiente método, se podría sobrecargar de las siguientes formas:

  • public void changeSize(int size, String name) { }
  • private int changeSize(int size, float pattern) { }
  • public void changeSize(float pattern, String name) throws IOException { }

Invocando a métodos sobrecargados

Si tenemos varios métodos sobrecargados en la misma clase, lo que va a determinar a cual se llamará de todos ellos son sus argumentos.

El tipo de objeto referenciado determina que método sobrecargado que será invocado.

Incluso el main puede ser sobrescrito, pero solo el que respete la firma será el invocado por la JVM.

Polimorfismo en métodos sobrecargados y sobrescritos

El polimorfismo no determina que versión sobrecargada se llamará de un método. Ejemplo:

public class Animal {
  public void eat() {
    System.out.println("Generic Animal Eating Generically");
   }
}
public class Horse extends Animal {
  public void eat() {
    System.out.println("Horse eating hay ");
  }
  public void eat(String s) {
    System.out.println("Horse eating " + s);
  }
}
Method Invocation Code Result
Animal a = new Animal(); a.eat(); Generic Animal Eating Generically
Horse h = new Horse();h.eat(); Horse eating hay
Animal ah = new Horse();ah.eat(); Horse eating hayPolymorphism works—the actual object type (Horse), not thereference type (Animal), is used to determine which eat() iscalled.
Horse he = new Horse();he.eat("Apples"); Horse eating ApplesThe overloaded eat(String s) method is invoked.
Animal a2 = new Animal();a2.eat("treats"); Compiler error! Compiler sees that the Animal class doesn't haveaneat() method that takes a String.
Animal ah2 = new Horse()ah2.eat("Carrots"); Compiler error! Compiler still looks only at the reference and seesthatAnimal doesn't have an eat() method that takes a String.Compiler doesn't care that the actual object might be aHorse atruntime.