Herança é uma pedra angular da programação orientada a objetos (POO), permitindo a criação de novas classes (filhas ou subclasses) com base em classes existentes (pai ou superclasses). Isso promove a reusabilidade do código, reduz a redundância e promove uma base de código bem estruturada. Este tutorial mergulha nos mecanismos de herança do Python, explorando vários tipos e demonstrando aplicações práticas.
Sumário
Sobrescrita de Método
Sobrescrita de método permite que uma subclasse forneça uma implementação especializada para um método herdado de sua superclasse. Isso personaliza o comportamento herdado sem alterar a superclasse.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print("Som de animal genérico")
class Dog(Animal):
def speak(self):
print("Au!")
class Cat(Animal):
def speak(self):
print("Miau!")
animal = Animal("Animal Genérico")
animal.speak() # Saída: Som de animal genérico
dog = Dog("Buddy")
dog.speak() # Saída: Au!
cat = Cat("Whiskers")
cat.speak() # Saída: Miau!
A função super()
permite acesso ao método da superclasse, permitindo que os comportamentos da superclasse e da subclasse sejam usados.
class Dog(Animal):
def speak(self):
super().speak()
print("Au! (da classe Dog)")
Herança Múltipla
Python suporta herança múltipla, onde uma classe herda de múltiplas classes pai, combinando funcionalidades. No entanto, gerenciar conflitos de nomes de métodos (o “problema do diamante”) requer consideração cuidadosa. A Ordem de Resolução de Métodos (ORM) do Python usando linearização C3 garante resolução de conflitos previsível. Você pode inspecionar a ORM usando ClassName.__mro__
.
class Flyer:
def move(self):
print("Voando!")
class Swimmer:
def move(self):
print("Nadando!")
class FlyingFish(Flyer, Swimmer):
pass
flying_fish = FlyingFish()
print(FlyingFish.__mro__) #Verificar ORM
flying_fish.move() # Saída: Voando! (o move do Flyer é chamado primeiro devido à ORM)
Herança Multinível
Herança multinível cria uma hierarquia onde uma subclasse herda de outra subclasse, que por sua vez herda de uma superclasse. Isso se baseia em classes existentes com especialização crescente.
class Animal:
def __init__(self, name):
self.name = name
class Mammal(Animal):
def __init__(self, name, fur_color):
super().__init__(name)
self.fur_color = fur_color
class Dog(Mammal):
def __init__(self, name, fur_color, breed):
super().__init__(name, fur_color)
self.breed = breed
dog = Dog("Buddy", "Marrom", "Golden Retriever")
print(f"{dog.name} é um {dog.breed} com pelo {dog.fur_color}.")
# Saída: Buddy é um Golden Retriever com pelo Marrom.
Exemplo Prático: Uma Hierarquia de Formas
Vamos ilustrar a herança com um exemplo prático: uma hierarquia de formas. Começaremos com uma classe base Shape
e derivaremos as classes Circle
e Rectangle
dela.
import math
class Shape:
def __init__(self, name):
self.name = name
def area(self):
raise NotImplementedError("Método area deve ser implementado em subclasses")
class Circle(Shape):
def __init__(self, name, radius):
super().__init__(name)
self.radius = radius
def area(self):
return math.pi * self.radius**2
class Rectangle(Shape):
def __init__(self, name, width, height):
super().__init__(name)
self.width = width
self.height = height
def area(self):
return self.width * self.height
circle = Circle("Círculo", 5)
rectangle = Rectangle("Retângulo", 4, 6)
print(f"A área do {circle.name} é: {circle.area()}")
print(f"A área do {rectangle.name} é: {rectangle.area()}")
Este exemplo mostra como a herança facilita a organização e a reusabilidade do código. O método area
é definido na classe base, forçando as subclasses a implementarem seus cálculos de área específicos.
Este tutorial fornece uma introdução abrangente à herança de classes em Python. A exploração adicional de classes base abstratas, interfaces e padrões de design que utilizam herança aumentará significativamente sua proficiência em POO.