Python para Desenvolvedores

2ª edição, revisada e ampliada

Capítulo 20: Herança múltipla


Na herança múltipla, a nova classe deriva de duas ou mais classes já existentes.

Exemplo:

In [1]:
class Terrestre(object):
    """
    Classe de veículos terrestres
    """
    se_move_em_terra = True

    def __init__(self, velocidade=100):
        """
        Inicializa o objeto
        """
        self.velocidade_em_terra = velocidade


class Aquatico(object):
    """
    Classe de veículos aquaticos
    """
    se_move_na_agua = True

    def __init__(self, velocidade=5):
        """
        Inicializa o objeto
        """
        self.velocidade_agua = velocidade


class Carro(Terrestre):
    """
    Classe de carros
    """
    rodas = 4

    def __init__(self, velocidade=120, pistoes=4):
        """
        Inicializa o objeto
        """
        self.pistoes = pistoes
        Terrestre.__init__(self, velocidade=velocidade)


class Barco(Aquatico):
    """
    Classe de barcos
    """
    def __init__(self, velocidade=6, helices=1):
        """
        Inicializa o objeto
        """
        self.helices = helices
        Aquatico.__init__(self, velocidade=velocidade)


class Anfibio(Carro, Barco):
    """
    Classe de anfíbios
    """
    def __init__(self, velocidade_em_terra=80,
        velocidade_na_agua=4, pistoes=6, helices=2):
        """
        Inicializa o objeto
        """
        # É preciso evocar o __init__ de cada classe pai
        Carro.__init__(self, velocidade=velocidade_em_terra,
            pistoes=pistoes)
        Barco.__init__(self, velocidade=velocidade_na_agua,
            helices=helices)


novo_anfibio = Anfibio()

for atr in dir(novo_anfibio):

    # Se não for método especial:
    if not atr.startswith('__'):
        print atr, '=', getattr(novo_anfibio, atr)
helices = 2
pistoes = 6
rodas = 4
se_move_em_terra = True
se_move_na_agua = True
velocidade_agua = 4
velocidade_em_terra = 80

A diferença mais significativa em relação à herança simples é a ordem de resolução de métodos (em inglês, Method Resolution Order- MRO).

MRO - Herança múltipla

Nas classes old style, a resolução começa pela classe mais a esquerda e desce até o fim da hierarquia e depois passa para o ramo a direita.

Já nas classes new style, a resolução é feita a partir da esquerda, descendo até encontrar a classe em comum entre os caminhos dentro hierarquia. Quando é encontrada uma classe em comum, a procura passa para o caminho à direita. Ao esgotar os caminhos, o algoritmo prossegue para a classe em comum e repete o processo.

Na hierarquia de classes do exemplo, a MRO para a classe dos anfíbios será:

[<class '__main__.Anfibio'>,
<class '__main__.Carro'>,
<class '__main__.Terrestre'>,
<class '__main__.Barco'>,
<class '__main__.Aquatico'>,
<type 'object'>]

A herança múltipla é um recurso que gera muita controvérsia, pois seu uso pode tornar o projeto confuso e obscuro.

In [1]:
 
Out[1]: