Árvore de Hierarquia de Classe/Entidade. Por Alexandre Morais da Rosa
Framework
Árvore de Hierarquia de Classe
Estrutura de classificação de tipos em programação orientada a objetos; organização hierárquica por relações de herança, do topo abstrato às especializações concretas.
Linguagem simples
Programas orientados a objetos organizam código em classes. Uma classe descreve dados e comportamento. Classes derivam de outras classes. A cadeia de derivação forma uma árvore [dependências; subordinadas]. No topo fica a classe mais geral; embaixo ficam as classes mais específicas.
Elementos Estruturais
Classe Base [raiz; primeira] | Define o estado e o comportamento mais genéricos, comuns a toda a árvore | Raiz única ou múltiplas raízes, conforme a linguagem |
Classe Derivada | Herda dados e métodos da classe pai; adiciona ou redefine comportamento | Redefinição indevida do contrato do pai quebra substituibilidade |
Relação de Herança | Liga classes por "estende", "herda", "é uma abstração de" | Herança de implementação difere de herança de interface |
Profundidade | Distância entre a raiz e a classe mais específica | Profundidade excessiva dificulta manutenção e leitura |
Multiplicidade de Raízes | Uma linguagem pode admitir uma ou várias raízes, com árvores que depois se fundem | Java tem raiz única [herança simples]; C++ admite múltiplas raízes |
Diagrama Estrutural
Representação em árvore, do topo [classe base] até as classes mais específicas, com variáveis e métodos fluindo de cima para baixo e podendo ser redefinidos em qualquer nível.

Quanto mais afastada da raiz, mais específica é a classe; variáveis e métodos declarados na raiz propagam-se para toda a árvore [herança], salvo redefinição em níveis inferiores.
Conceito e Classificação
A árvore de hierarquia de classes [também chamada árvore de herança] classifica objetos definindo-os como instâncias de classes e conectando grupos de classes por relações de herança: "estende", "herda", "é uma abstração de", "implementa uma interface". A classe é determinada em termos de outras classes e define o estado e o comportamento dos objetos daquele tipo. No topo da hierarquia está uma "Classe Base"; as demais derivam dela, formando uma estrutura em árvore. A profundidade da hierarquia depende do problema modelado; a forma exata da árvore depende da linguagem utilizada.
Em algumas linguagens, a hierarquia admite múltiplas raízes e várias árvores independentes, que posteriormente podem se fundir por composição ou por meio de interfaces comuns. Linguagens como Java restringem a herança de implementação a uma única raiz por classe [herança simples], de modo que a árvore de classes de qualquer programa Java converge para uma única raiz.
Árvore de hierarquia de classe | Herança [é um] | Subclasse reaproveita e especializa o comportamento do pai |
Composição de objetos | Contém [tem um] | Um objeto referencia outro, em vez de herdar dele |
Hierarquia de interfaces | Implementa [contrato] | Define comportamento exigido, sem herdar implementação |
Grafo de dependência de módulos | Importa/usa | Relação de uso entre unidades de código, não de tipo |
Regras por linguagem
Java | Simples [uma superclasse por classe] | Única; toda classe deriva, direta ou indiretamente, de Object |
Python | Múltipla [várias superclasses por classe] | Única em CPython moderno [object], com resolução de método por C3 linearization |
C++ | Múltipla | Sem raiz universal obrigatória; podem coexistir várias árvores independentes |
C# | Simples para classes; múltipla para interfaces | Única; toda classe deriva de System.Object |
Nota: "herança múltipla" é tema de controvérsia de projeto de linguagem. Linguagens que a permitem [C++, Python] resolvem ambiguidades de método por regras próprias de precedência; linguagens que a proíbem para classes [Java, C#] a reintroduzem parcialmente via interfaces com métodos default. Não há consenso único sobre qual abordagem é superior.
Checklist ao desenhar uma hierarquia
Subclasse mantém o contrato comportamental da classe pai [substituibilidade; toda subclasse deve poder substituir a instância do pai sem quebrar o código cliente]
Profundidade da árvore compatível com a complexidade real do domínio modelado, sem níveis intermediários sem propósito
Herança usada apenas para relação "é um"; relação "tem um" resolvida por composição
Redefinição de método em subclasse documentada, explicitando o que muda em relação ao comportamento herdado
Classes abstratas e interfaces distinguidas de classes concretas na representação gráfica da árvore
Raiz da hierarquia coerente com a convenção da linguagem [raiz única ou múltiplas raízes]
Erros mais comuns
Erro 1: herança usada para reaproveitar código sem relação "é um". Uma classe herda de outra apenas para reutilizar métodos, sem que exista relação de especialização real. Correção: extrair o comportamento comum para um objeto associado e usar composição.
Erro 2: hierarquia profunda demais. Cadeias de herança com muitos níveis tornam difícil saber onde um comportamento foi definido. Correção: achatar a hierarquia, preferindo composição e interfaces a partir de determinado nível de profundidade.
Erro 3: quebra de substituibilidade [princípio de Liskov]. Subclasse redefine um método de forma que instâncias dela não podem substituir instâncias da classe pai sem quebrar o comportamento esperado. Correção: revisar a pré-condição e a pós-condição do método redefinido.
Erro 4: confundir herança de implementação com herança de interface. Tratar "implementa uma interface" e "estende uma classe" como equivalentes gera acoplamento desnecessário. Correção: separar o contrato [interface] da implementação concreta [classe].
Erro 5: ambiguidade em herança múltipla. Duas superclasses definem o mesmo método com assinatura igual e a subclasse não resolve explicitamente qual prevalece. Correção: seguir a regra de resolução da linguagem ou redefinir explicitamente o método na subclasse.
Exemplo didático
Java, herança simples, raiz única
class Veiculo {
protected int velocidadeMaxima;
void mover() { System.out.println("Movendo"); }
}
class Carro extends Veiculo {
void mover() { System.out.println("Rodando sobre rodas"); }
}
class CarroEletrico extends Carro {
private int autonomiaKm;
@Override
void mover() { System.out.println("Rodando em silencio"); }
}Python, herança múltipla
class Voador:
def mover(self):
print("Voando")
class Nadador:
def mover(self):
print("Nadando")
class PatoRobo(Voador, Nadador):
pass # resolucao de mover() segue a ordem de resolucao de metodo [MRO]Perguntas frequentes
Toda linguagem orientada a objetos tem raiz única? Não. Java e C# impõem raiz única para classes. C++ não exige raiz universal; é possível ter várias árvores de classe independentes no mesmo programa.
Qual a diferença entre herança e implementação de interface? Herança de classe traz implementação herdada do pai; implementação de interface traz apenas um contrato a cumprir, sem herdar código pronto, ressalvados métodos default, quando a linguagem os admite.
Herança profunda é sempre um problema? Não por si só; o problema surge quando a profundidade não corresponde a uma especialização real do domínio.
Composição substitui herança? Não em toda situação. Composição resolve relações "tem um"; herança continua adequada para relações "é um", com verdadeira substituibilidade entre pai e subclasse.
Glossário
Classe Base | Classe no topo da hierarquia, da qual as demais derivam direta ou indiretamente |
Subclasse | Classe que herda dados e comportamento de uma classe pai, podendo redefini-los |
Herança simples | Restrição segundo a qual uma classe deriva de apenas uma superclasse |
Herança múltipla | Possibilidade de uma classe derivar de mais de uma superclasse simultaneamente |
Substituibilidade [Liskov] | Propriedade pela qual uma instância de subclasse pode substituir uma instância da classe pai sem quebrar o programa |
Composição | Relação "tem um", em que um objeto referencia outro em vez de herdar dele |
