Oi Rodrigo, tudo bom?
Nesse caso, a semantica é quem deve mandar. Ou seja, aqui a gente aplica o verbo ser entre as classes e vê o que faz sentido. Se a frase fizer sentido a gente usa herança. Algo como:
Animal é Espécie? (não, animal é um reino)
Animal é Proprietário? (obviamente, não)
Proprietário é Animal? (sim, pela definição biologica pelo menos)
Então daqui sabemos que Proprietario herda de Animal.
Porém, a questão de espécies, como fica?
Pela definição biológica, Temos Reinos, Filos, Classes, Ordens, Familias, Generos e Especies.
Ou seja, o Reino animal, tem muitas classes, que tem muitas ordens, que tem muitas familias, generos e por fim tem muitas especies.
Isso significa que um Reino tem muitas Especies. Logo, nesse caso a semântica aponta para que a gente use composição ao invés de herança =)
Assim, a classe Especie seria um atributo dentro da classe Animal.
Nosso diagrama de classes ficaria algo como:
Animal extends Reino
-> atributo especies (lista do tipo Especie)
Proprietario extends Animal
Assim, mantemos a responsabilidade de Proprietário dentro da classe Proprietario, as de comportamentos e atributos comuns a animais em Animal e Especie de especies dentro de Especie.
Acho que aqui já temos uma boa representação do cenário. Porém, podemos ir além representando melhor a Especie. Pensando bem, uma Especie é também um animal. Logo, podemos fazer algo como:
Especie extends Animal
Isso faria com que a composição dentro da classe Animal se tornasse um relacionamento entre a classe Animal com a classe Especie (que herda de Animal também).
Perceba que todo mundo meio que acaba herdando de animal porque é um conceito biológico muito abstrato, todo ser vivo que não é uma planta basicamente é um animal, então podemos ir longe nesse exemplo.
O que importa aqui para garantir o principio de responsabilidade única, é olhar pro seu problema (regra de negocio) e aplicar essas regras semânticas do verbo ser e do verbo ter para não cair em uma herança errada e usar composição nas horas certas. Sempre pensando se o que você está atribuindo aquela classe realmente faz sentido. Por exemplo, você não colocaria um método voar()
dentro da classe Proprietario porque não é responsabilidade de um proprietario voar. Faz sentido? =)
Abraço