Вероятно, так же, как это делает Java (Java 5 поддерживает ковариантные возвраты на уровне языка, но JVM не поддерживает его): путем добавления синтетических методов. Вот как это делает Java: скажем, у вас есть такой класс:
class Foo implements Cloneable {
@Override
public Foo clone() {
// ...
}
}
За кулисами генерируются два clone
метода: public Foo clone()
(который содержит реальный код) и public Object clone()
(который просто возвращает результат первого). Последний метод (который синтезируется) - это способ переопределения метода clone
на уровне JVM.