Classes
Herança
Uma característica importante de classes é que podemos criar extensões de uma classe, adicionando mais atributos ou métodos, ou até mesmo modificando métodos que já existiam anteriormente. Não vamos entrar em detalhes, pois isso será o foco de discussões do próximo semestre, mas apresentaremos algumas noções neste handout.
Suponha que estamos implementando um sistema para o controle do aluguel de carros. Nesse sistema, nós temos diversos tipos de usuário, mas todos os usuários possuem um login e senha.
Exercício 1
Resposta
O __init__
é o construtor da classe Usuario
. Ele recebe os argumentos login
e senha
e armazena esses valores no objeto recém criado (self
).
Agora, suponha que queremos criar um tipo especial de usuário, o colaborador. O usuário colaborador possui um atributo adicional, o salário. Assim, queremos que o colaborador tenha tudo o que o usuário tem e mais algumas coisas. Um detalhe importante aqui: o colaborador é um Usuario
com mais algumas coisas, ou seja, ele estende a classe Usuario
. Esse é o conceito de herança em programação: podemos criar uma classe herda os atributos e métodos de outra e adiciona ou modifica a sua funcionalidade. Isso é feito em Python1 colocando o nome da classe da qual estamos herdando entre parênteses: class Colaborador(Usuario)
.
Vamos agora pensar no restante do código da classe Colaborador
.
Exercício 2
Resposta
Como um Colaborador
é um Usuario
, ele deveria ter um login e senha, mas ele possui apenas um atributo salario
.
Todo Usuario
possui login e senha, portanto o Colaborador
também deveria ter esses atributos. O código abaixo poderia resolver esse problema:
class Colaborador(Usuario):
def __init__(self, login, senha, salario):
self.login = login
self.senha = senha
self.salario = salario
Entretanto, o construtor da classe Usuario
já armazena o login e a senha. Para utilizar o construtor da classe mãe (também chamda de superclasse) a partir do código da classe filha, podemos usar a função super()
:
class Colaborador(Usuario):
def __init__(self, login, senha, salario):
super().__init__(login, senha) # Chama o construtor da superclasse
self.salario = salario
É possível fazer muito mais com herança, mas deixaremos essa discussão para o segundo semestre.
-
Cuidado! É muito comum abusarmos do uso de herança quando aprendemos esse conceito. A herança deve ser usada com moderação, apenas quando realmente faz sentido. Uma maneira de avaliar se uma herança faz sentido é utilizando o "é um". Se for razoável dizer que um objeto de uma classe filha também é um objeto da classe mãe, a herança pode fazer sentido. Caso contrário, procure evitar. No nosso exemplo, um
Colaborador
é umUsuario
. Note que o contrário não faz sentido: umUsuario
não necessariamente é umColaborador
. ↩