Eu acho que seria legal que tanto trolls quanto lobisomens herdassem seus atributos do inimigo e substituíssem alguns deles.
Infelizmente, essa abordagem do polimorfismo, popular nos anos 90, mostrou-se uma má ideia na prática. Imagine que você adicione 'wolf' à lista de inimigos - bem, ele compartilha alguns atributos com o lobisomem, então você deseja consolidá-los em uma classe base compartilhada, por exemplo. 'WolfLike'. Agora você adiciona 'Humano' à lista de inimigos, mas os lobisomens às vezes são humanos, então eles também compartilham atributos, como andar com duas pernas, poder conversar, etc. Você cria uma base comum 'Humanóide' para humanos e lobisomens , e você precisa parar de lobisomens derivados de WolfLike? Ou você multiplica a herança de ambos - nesse caso, qual atributo tem precedência quando algo no Humanoid colide com algo no WolfLike?
O problema é que tentar e modelar o mundo real como uma árvore de classes é ineficaz. Faça três coisas e provavelmente você pode encontrar quatro maneiras diferentes de fatorar o comportamento deles em compartilhado e não compartilhado. É por isso que muitos optaram por um modelo modular ou baseado em componente, onde um objeto é composto por vários objetos menores que compõem o todo, e os objetos menores podem ser trocados ou alterados para criar o comportamento desejado. Aqui você pode ter apenas 1 classe Inimigo e contém subobjetos ou componentes de como anda (por exemplo: Bipedal vs. Quadrupedal), seus métodos de ataque (por exemplo: mordida, garra, arma, punho), sua pele (verde para trolls, peludo para lobisomens e lobos), etc.
Isso ainda é completamente orientado a objetos, mas a noção do que é um objeto útil é diferente do que costumava ser ensinado nos livros didáticos. Em vez de ter uma grande árvore de herança de várias classes abstratas e várias classes concretas nas pontas da árvore, você normalmente tem apenas 1 classe concreta representando um conceito abstrato (por exemplo, 'inimigo'), mas que contém mais classes concretas representando conceitos mais abstratos (por exemplo, ataques, tipo de pele). Às vezes, essas segundas classes podem ser melhor implementadas por meio de um nível de herança (por exemplo, uma classe de ataque básica e várias classes derivadas para ataques específicos), mas a árvore de herança profunda desapareceu.
Mas talvez as aulas sejam muito pesadas para serem práticas, eu não sei ...
Na maioria dos idiomas modernos, as aulas não são 'pesadas'. Eles são apenas outra maneira de escrever código e geralmente envolvem a abordagem processual que você teria escrito de qualquer maneira, exceto com uma sintaxe mais fácil. Mas, por todos os meios, não escreva uma classe onde uma função funcionará. As classes não são intrinsecamente melhores, apenas onde elas tornam o código mais fácil de gerenciar ou entender.