In Apex, use virtual / abstract on the parent,override on the child.
Animal a = new Dog();
Woof!
Method resolved on the real instance type.
public virtual class Animal {
public virtual String speak() {
return '…';
}
}
public class Dog extends Animal {
public override String speak() {
return 'Woof';
}
}