Polymorphism: dynamic dispatch and toString() · Polimorfismo: despacho dinámico y toString()
Polymorphism: one type, many behaviours
- Polymorphism means "many forms": one superclass type, many subclass behaviours.
- You can hold a
Dogor aCatin anAnimalvariable, because each is-anAnimal. - When you call a method, the object's real type decides which version runs.
Polimorfismo: un tipo, muchos comportamientos
- Polimorfismo significa "muchas formas": un tipo de superclase, muchos comportamientos de subclase.
- Puedes guardar un
Dogo unCaten una variableAnimal, porque cada uno es-unAnimal. - Cuando llamas a un método, el tipo real del objeto decide qué versión se ejecuta.
Dynamic dispatch
- The variable's type (
Animal) decides which methods you are allowed to call. - But at run time, the actual object (
Dog) decides which overridden version runs. - This run-time choice is called dynamic dispatch — it is the heart of polymorphism.
Despacho dinámico
- El tipo de la variable (
Animal) decide qué métodos estás permitido llamar. - Pero en tiempo de ejecución, el objeto real (
Dog) decide qué versión sobrescrita se ejecuta. - Esta elección en tiempo de ejecución se llama despacho dinámico: es el corazón del polimorfismo.
public class Main {
public static void main(String[] args) {
Animal[] zoo = { new Dog(), new Cat(), new Dog() };
for (Animal a : zoo) {
System.out.println(a.speak()); // Woof, then Meow, then Woof
}
}
}
class Animal {
public String speak() { return "some sound"; }
}
class Dog extends Animal {
public String speak() { return "Woof"; }
}
class Cat extends Animal {
public String speak() { return "Meow"; }
}
One loop handles every subclass
- The loop above never asks "is this a Dog or a Cat?" — it just calls
speak(). - Each object answers in its own way. That keeps the loop short and general.
- Add a brand-new subclass later and the same loop works on it, unchanged.
Un solo bucle maneja todas las subclases
- El bucle anterior nunca pregunta "¿es este un Dog o un Cat?": simplemente llama a
speak(). - Cada objeto responde a su propia manera. Eso mantiene el bucle corto y general.
- Si agregas una nueva subclase más adelante, el mismo bucle funciona con ella sin cambios.
toString(): every object inherits it from Object
- Every class in Java secretly extends a class called
Object, which has atoString(). - Override
toString()to say how your object should look as text. - Java calls it automatically when you print an object or join it with
+.
toString(): todo objeto lo hereda de Object
- Toda clase en Java hereda secretamente de una clase llamada
Object, que tiene untoString(). - Sobrescribe
toString()para indicar cómo debe verse tu objeto como texto. - Java lo llama automáticamente cuando imprimes un objeto o lo concatenas con
+.
public class Main {
public static void main(String[] args) {
Object x = new Fraction(3, 4);
System.out.println(x); // 3/4 -- toString() runs
System.out.println("ratio " + x); // ratio 3/4
}
}
class Fraction {
private int numerator;
private int denominator;
public Fraction(int numerator, int denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
public String toString() {
return numerator + "/" + denominator;
}
}
Common mistakes
- The actual object's method runs at run time (dynamic dispatch), not the variable's type.
- Override
toString()for readable output.
Errores comunes
- En tiempo de ejecución se ejecuta el método del objeto real (despacho dinámico), no el tipo de la variable.
- Sobreescribe
toString()para obtener una salida legible.
Now you try
- Use a superclass array, add a new subclass, and override
toString(). - A hidden Harness checks that the right version runs for each object.
- Press Run to compile, then Check answer. Your code runs on the server, so even the first run is fast.
Ahora tú intentarlo
- Usa un array de superclase, agrega una nueva subclase y sobrescribe
toString(). - Una Herramienta oculta verifica que se ejecute la versión correcta para cada objeto.
- Presiona Run para compilar, luego Check answer. Tu código se ejecuta en el servidor, así que incluso la primera ejecución es rápida.
Animal, Dog, and Cat are written for you. Complete the static method Zoo.chorus(Animal[] animals) so it returns every animal's sound joined by single spaces. Example: a Dog, Cat, Dog array gives "Woof Meow Woof". An empty array gives "". Loop and call speak() — let polymorphism pick the right sound. · Animal, Dog y Cat ya están definidos. Completa el método estático Zoo.chorus(Animal[] animals) para que devuelva los sonidos de cada animal unidos por espacios simples. Ejemplo: un array con Dog, Cat, Dog devuelve "Woof Meow Woof". Un array vacío devuelve "". Usa un bucle y llama a speak() — deja que el polimorfismo seleccione el sonido correcto.
Click Run to see the output here. · Haz clic en Ejecutar para ver la salida aquí.
Animal, Dog, Cat, and a working Zoo.chorus are written for you. Add a class Cow that extends Animal and overrides speak() to return "Moo". Notice the existing chorus loop handles your new Cow with no changes. · Animal, Dog, Cat y un Zoo.chorus funcional están escritos para ti. Añade una clase Cow que extienda Animal y sobreescriba speak() para devolver "Moo". Observa que el bucle chorus existente maneja tu nueva Cow con ningún cambio.
Click Run to see the output here. · Haz clic en Ejecutar para ver la salida aquí.
Complete Fraction by overriding toString() so it returns the fraction as "numerator/denominator" — for 3 and · y 4 it returns "3/4". Java calls toString() automatically when you print a Fraction or join it with +. · Completa Fraction sobrescribiendo toString() para que devuelva la fracción como "numerator/denominator" — para 3 y 4 devuelve "3/4". Java llama a toString() automáticamente cuando imprimes un Fraction o lo unes con +.
Click Run to see the output here. · Haz clic en Ejecutar para ver la salida aquí.