Dynamic Dispatch

Objective: Create container accepting items of different types. Categorize items in runtime. Dispatch methods dynamically.

Python

from typing import Union, List

class Cat:
    def make_sound(self):
        print("miao")
        
class Cow:
    def make_sound(self):
        print("mooo")

Animal = Union[Cat, Cow]
animals: List[Animal] = []
animals.append( Cat() )
animals.append( Cow() )

for animal in animals:
    animal.make_sound()
    

Alternatively, instead of using Union type, classes Cat and Cow can have common base Animal.

Rust

trait CanMakeSound {
    fn make_sound(&self);
}

struct Cat {
}

impl CanMakeSound for Cat {
    fn make_sound(&self) {
        println!("miao")
    }
}
    
struct Cow {
}

impl CanMakeSound for Cow {
    fn make_sound(&self) {
        println!("mooo")
    }
}

fn main() {

    let mut animals: Vec<&dyn CanMakeSound> = Vec::new();
    animals.push( &Cat{} );
    animals.push( &Cow{} );

    for animal in animals {
    animal.make_sound();
    }
 
}

Alternatively:

fn main() {

    let mut animals: Vec<Box<dyn CanMakeSound>> = Vec::new();
    animals.push( Box::new(Cat{}) );
    animals.push( Box::new(Cow{}) );

    for animal in animals {
    animal.make_sound();
    }

}

Crystal

class Cat
  def make_sound
    puts "miao"
  end
end

class Cow
  def make_sound
    puts "mooo"
  end
end

alias Animal = Cat | Cow
animals = [] of Animal
animals << Cat.new
animals << Cow.new

animals.each &.make_sound()

Alternatively:

animals.each do |animal|
  animal.make_sound
end