In the following scenario, Main.registerEvents(Listener) is part of an event system of a game API.
Let's say it should register any method with the @EventHandler annotation.
public abstract class Spell implements Listener {
protected Spell() {
Main.getInstance().registerEvents(this);
}
@EventHandler
public void onMove(PlayerMoveEvent event) {
}
}
public class Fireball extends Spell {
@EventHandler
public void onChat(PlayerChatEvent event) {
}
}
Generally speaking, since this refers to the current instance, how is it possible that Fireball.onChat(PlayerChatEvent) is registered too?

Generally speaking, since this refers to the current instance, how is it possible that Fireball.onChat(PlayerChatEvent) is registered too?
Because when you're constructing an instance of Fireball, this refers to the Fireball being constructed at execution time. The compile-time type of this is Spell, but if you print out this.getClass() (even within the Spell constructor) it will show Fireball.
Therefore if registerEvents is looking at the execution-time type of the object and finding event handlers with reflection, it will see onChat.
See more on this question at Stackoverflow