Olá! Esta é a continuação do curso de Orientação a Objetos com Python. Nosso objetivo será reforçar o conhecimento sobre esse assunto, falaremos sobre alguns aspectos idiomáticos da linguagem, que nos auxiliarão a atuar com Python. Além disso, trataremos aspectos específicos da Orientação a Objeto e como eles são aplicados nesta linguagem.
Por exemplo, herança, polimorfismo e Duck Typing. Falaremos também sobre herança múltipla, um aspecto que pode assustar algumas pessoas, mas apresentaremos de forma sucinta, deixando claro o conceito.
Abordaremos o assunto mixin, falaremos de forma a garantir maior segurança quando trabalharmos com um código Python. Outra situação que podemos encontrar será o código no qual seja exigida uma interface mais ligada aos aspectos desta linguagem.
Tentaremos introduzir esse conhecimento para a linguagem Pyhton ligado a O.O., um tema que este será o foco nesta parte, mas que provavelmente será abordado em outros cursos.
Espero que você goste, vamos praticar bastante!
Começaremos o curso abordando o nosso primeiro assunto, no qual relembraremos classes e objetos. Nós pensaremos em trechos de uma aplicação para absorver melhor esses conceitos de O.O. no Python e tentar entendê-los de uma forma mais tranquila.
Primeiramente lidaremos com este trecho de aplicação, com a qual teremos o controle de playlist de programa de TV. Podemos lidar com filmes, séries, documentários e afins. Começaremos pelo filme - cujo modelo faremos no Python.
Um filme tem as seguintes características:
Uma série, por sua vez, possui:
A partir dessas informações, tentaremos construir um modelo usando a linguagem Python. Para isto, abriremos o PyCharm e criaremos um projeto que receberá o nome python3oo2
. Com o número 2
indicamos que é um arquivo referente à segunda parte do curso de O.O..
No interpretador, deixaremos o arquivo configurado com "Python 3.6", por ele já estar instalado na máquina. Em seguida, criaremos o arquivo Modelo.py
, nome geralmente usado ao criarmos conceitos de classe os quais representarão um domínio no nosso sistema. Criados o projeto e o modelo, começaremos a trabalhar com o código.
Inicialmente, adicionaremos class Filme
- o que precisaremos fazer para criar uma classe? Podemos definir o que será necessário para criar um objeto deste tipo, e teríamos que começar do inicializador. Isso é necessário sempre?
O Python possui uma flexibilidade, que permite que criemos um objeto ao colocarmos pass
e indicarmos que simplesmente estamos passando-o. Por exemplo, trabalharemos com o filme vingadores
, em seguida verificaremos se o objeto está pronto, com print()
.
class Filme:
pass
vingadores = Filme()
print(vingadores)
Até o momento, vingadores
não possui um atributo, a ideia é simplesmente demonstrar que conseguimos criar um objeto de uma classe de forma muito flexível. Se clicarmos com o botão direito e selecionarmos "Run 'modelo'", o PyCharm vai imprimir no console as informações, algumas da memória do Python:
C:\Users\Alura\Appdata\Local\Progrms\Python\Python36-32\pythosn.exe\luan.silva
<_mains_.Filme object at 0x050220F0>
Process finished with code 0
Assim, são exibidas as informações correspondentes ao tentarmos imprimir um objeto que seja do tipo filme. Agora vamos modelar essa classe, que na verdade não possui apenas pass
, e sim atributos como def
, com o qual definiremos o inicializador ( __init__
):
class Filme:
def __init__(self, nome, ano, duracao):
self.nome = nome
self.ano = ano
self.duracao = duracao
vingadores = Filme()
print(vingadores.nome)
O inicializador __init__
sempre receberá self
, e também passaremos outros atributos: nome
, ano
e duracao
. Com estes três devemos preencher os três valores do objeto na nossa instancia. Por isso usamos self.nome
, self.ano
e self.duracao
. A partir de agora podemos pedir para que se imprima especificamente o nome do filme, passando para print
o vingadores.nome
.
Se executarmos novamente o modelo, veremos uma mensagem de erro: TypeError: __init__() missing 3 required positional arguments
- fomos avisados de que temos um inicializador com mais argumentos, e que faltou passá-los no código.
vingadores = Filme('vingadores - guerra infinita', 2018, 160)
print(vingadores.nome)
Se executarmos novamente com "Run 'modelo'", veremos impresso:
vingadores - guerra infinita
Em seguida, incluiremos class Serie
, podendo-se inclusive aproveitar o código da primeira.
class Filme:
def __init__(self, nome, ano, duracao):
self.nome = nome
self.ano = ano
self.duracao = duracao
class Serie:
def __init__(self, nome, ano, temporadas):
self.nome = nome
self.ano = ano
self.temporadas = temporadas
vingadores = Filme('vingadores - guerra infinita', 2018, 160)
print(vingadores.nome)
atlanta = Serie('atlanta', 2018, 2)
print(f'Nome: {atlanta.nome} - Ano: {atlanta.ano} - Temporadas: {atlanta.temporadas}')
Passaremos como série atlanta
, isto é, será igual a Serie()
, com os valores correspondentes em relação aos atributos nome
, ano
e temporadas
. No caso, ela tem o total de 2
temporadas, e imprimiremos além do nome, a anotação de formatação do Python 3.6. Dentro de {}
incluiremos o atributo que queremos imprimir. Observe que, desta vez, adicionamos outras informações na string.
Ao executarmos o código, veremos impresso no console:
vingadores - guerra infinita
Nome: atlanta - Ano: 2018 - Temporadas: 2
Vamos tornar esse informação mais compreensível agregando mais informações em Filme
.
class Filme:
def __init__(self, nome, ano, duracao):
self.nome = nome
self.ano = ano
self.duracao = duracao
class Serie:
def __init__(self, nome, ano, temporadas):
self.nome = nome
self.ano = ano
self.temporadas = temporadas
vingadores = Filme('vingadores - guerra infinita', 2018, 160)
print(f'Nome: {vingadores.nome} - Ano: {vingadores.ano} - Duração: {vingadores.duracao}')
atlanta = Serie('atlanta', 2018, 2)
print(f'Nome: {atlanta.nome} - Ano: {atlanta.ano} - Temporadas: {atlanta.temporadas}')
A impressão ficará da seguinte maneira:
Nome: vingadores - guerra infinita - Ano: 2018 - Duração: 160
Nome: atlanta - ano: 2018 - Temporadas: 2
Relembrando como é criar uma classe e um objeto da mesma... Para onde isso nos leva?
Por enquanto temos nossa aplicação funcionando, mas é normal termos que lidar com informações novas. As aplicações mudam, é normal. No caso, temos uma informação nova: além das informações já disponibilizadas, teremos a quantidade de likes. Será necessário implementarmos uma funcionalidade que indique a popularidade daquela série.
Teremos também uma regra que nos dirá que, sempre que for um filme for inserido, colocaremos um nome específico. No momento em que imprimirmos filme.nome
, devemos fazê-lo de forma que Meu Filme
esteja com as primeiras letras em maiúsculo.
Nós ainda estamos imprimindo meu filme
de forma diferente, mas foi algo dentro do código que conseguiu exibir o texto da forma modificada. Falta implementarmos esta regra de negócio tanto para filmes como para séries.
Vemos que já temos código para fazer, essa será nossa missão a seguir. Mas antes, recomendo que você faça os exercícios de fixação dos conceitos vistos até agora.
Vamos continuar a escrever os trechos de código referentes a Filme
e Serie
. Falamos anteriormente que acrescentaríamos algumas regras: ambos os tipos devem informar a quantidade de likes recebida, ou seja, eles passarão a ideia de sua popularidade para a classe.
Outro ponto será a inclusão de um comportamento ao exibirmos um nome de determinada maneira, quando criarmos um objeto do tipo Filme
, ao incluirmos meu filme
ou meu nome
e o colocarmos em nome
. Quando passarmos esse elemento pelo inicializador, imprimiremos um nome e este será exibido com as primeiras letras de cada palavra em maiúsculo como em Meu Filme
. O mesmo deverá acontecer em relação às séries.
Resolveremos essa questão trabalhando no código, de volta à IDE:
class Filme:
def __init__(self, nome, ano, duracao):
self.nome = nome
self.ano = ano
self.duracao = duracao
class Serie:
def __init__(self, nome, ano, temporadas):
self.nome = nome
self.ano = ano
self.temporadas = temporadas
vingadores = Filme('vingadores - guerra infinita', 2018, 160)
print(f'Nome: {vingadores.nome} - Ano: {vingadores.ano} '
f'- Duração: {vingadores.duracao}')
atlanta = Serie('atlanta', 2018, 2)
print(f'Nome: {atlanta.nome} - Ano: {atlanta.ano} '
f'- Temporadas: {atlanta.temporadas}')
O próximo passo será incluir a informação do nome e depois, transformá-lo. Como podemos fazer isso? Investigaremos como funciona a biblioteca de string do Python. Começaremos experimentando a função capitalize()
para vermos como isso irá refletir no momento da impressão.
class Filme:
def __init__(self, nome, ano, duracao):
self.nome = nome.capitalize()
self.ano = ano
self.duracao = duracao
No console, o nome do filme será impresso da seguinte forma:
Nome: Vingadores - guerra infinita - Ano: 2018 - Duração: 160
Nome: atlanta - ano: 2018 - Temporadas: 2
A primeira letra do nome já foi impressa em maiúsculo, mas as demais não. Ao incluirmos capitalize()
, podemos "capitalizar" a primeira letra para deixá-la em caixa alta, mas ainda não é bem o que queremos. Vamos testar outra função, title()
, e ver se conseguimos modificar o comportamento. Faremos o mesmo na série.
class Filme:
def __init__(self, nome, ano, duracao):
self.nome = nome.title()
self.ano = ano
self.duracao = duracao
class Serie:
def __init__(self, nome, ano, temporadas):
self.nome = nome.title()
self.ano = ano
self.temporadas = temporadas
Com o uso do title()
teremos o resultado esperado:
Nome: Vingadores - Guerra Infinita - Ano: 2018 - Duração: 160
Nome: Atlanta - ano: 2018 - Temporadas: 2
Agora falta implementar os likes. Porém, não basta incluir o valor dos likes no momento em que criamos Filme
, pois este será um elemento incremental. Como faremos para definir algo que será modificado posteriormente, e que não será definido no momento da criação do objeto? Devemos ter um método para inserir a informação e modificar seu estado recém criado.
Também definiremos um método com a utilidade de dar like, sem receber parâmetros e que, no fim, adicionará +1
à contagem de likes.
class Filme:
def __init__(self, nome, ano, duracao):
self.nome = nome.title()
self.ano = ano
self.duracao = duracao
def dar_like(self):
self.likes += 1
Conseguimos dar likes, mas e a exibição desse valor? Para isto, podemos criar uma função, ou colocar likes
dentro do construtor. Mas dessa vez sua utilidade não será para definir um valor específico, e sim, inicial. No caso, será igual a 0
.
class Filme:
def __init__(self, nome, ano, duracao):
self.nome = nome.title()
self.ano = ano
self.duracao = duracao
self.likes = 0
def dar_like(self):
self.likes += 1
O próximo passo será replicar o mesmo comportamento para Serie
.
class Serie:
def __init__(self, nome, ano, temporadas):
self.nome = nome.title()
self.ano = ano
self.temporadas = temporadas
self.likes = 0
def dar_like(self):
self.likes += 1
Lembre-se que no construtor não iremos receber likes, ele sempre começará com o valor igual a 0
, sem termos influência do usuário. Agora, adicionaremos o texto da string para exibirmos a popularidade.
vingadores = Filme('vingadores - guerra infinita', 2018, 160)
print(f'Nome: {vingadores.nome} - Ano: {vingadores.ano} '
f'- Duração: {vingadores.duracao} - Likes: {vingadores.likes}')
atlanta = Serie('atlanta', 2018, 2)
print(f'Nome: {atlanta.nome} - Ano: {atlanta.ano} '
f'- Temporadas: {atlanta.temporadas} - Likes: {atlanta.likes}')
Temos muitos trechos de código repetido, mas resolveremos isso mais adiante. Em seguida, executaremos o código:
Nome: Vingadores - Guerra Infinita - Ano: 2018 - Duração: 160 - Likes: 0
Nome: Atlanta - ano: 2018 - Temporadas: 2 - Likes: 0
Para adicionarmos um like, podemos usar a função dar_like()
, o que faremos duas vezes para atlanta
e uma para vingadores
.
vingadores = Filme('vingadores - guerra infinita', 2018, 160)
print(f'Nome: {vingadores.nome} - Ano: {vingadores.ano} '
f'- Duração: {vingadores.duracao} - Likes: {vingadores.likes}')
vingadores.dar_like()
atlanta = Serie('atlanta', 2018, 2)
print(f'Nome: {atlanta.nome} - Ano: {atlanta.ano} '
f'- Temporadas: {atlanta.temporadas} - Likes: {atlanta.likes}')
atlanta.dar_like()
atlanta.dar_like()
Entretanto, se executarmos o código, o valor de Likes
continuará igual a 0
. Por que isso aconteceu? A questão é que incluímos o like
após o print()
, e resolveremos o assunto se mudarmos a ordem das linhas.
vingadores = Filme('vingadores - guerra infinita', 2018, 160)
vingadores.dar_like()
print(f'Nome: {vingadores.nome} - Ano: {vingadores.ano} '
f'- Duração: {vingadores.duracao} - Likes: {vingadores.likes}')
atlanta = Serie('atlanta', 2018, 2)
atlanta.dar_like()
atlanta.dar_like()
print(f'Nome: {atlanta.nome} - Ano: {atlanta.ano} '
f'- Temporadas: {atlanta.temporadas} - Likes: {atlanta.likes}')
Com os print()
s depois dos likes, teremos o seguinte resultado:
Nome: Vingadores - Guerra Infinita - Ano: 2018 - Duração: 160 - Likes: 1
Nome: Atlanta - ano: 2018 - Temporadas: 2 - Likes: 2
Já conseguimos dar likes, fizemos as tarefas propostas, mas temos algumas falhas. Por exemplo, definimos que o nome é titularizado, porém, se adicionarmos uma nova linha com atlanta.nome
no código, logo abaixo de atlanta
, ele deixará de fazer a alteração nas letras.
atlanta = Serie('atlanta', 2018, 2)
atlanta.nome = 'atlanta'
atlanta.dar_like()
atlanta.dar_like()
print(f'Nome: {atlanta.nome} - Ano: {atlanta.ano} '
f'- Temporadas: {atlanta.temporadas} - Likes: {atlanta.likes}')
No console, veremos:
Nome: Vingadores - Guerra Infinita - Ano: 2018 - Duração: 160 - Likes: 1
Nome: atlanta - ano: 2018 - Temporadas: 2 - Likes: 2
O problema aconteceu porque não estamos protegendo o nome do atributo, este é alterado apenas no momento da criação, mas e depois? Como definiremos set
do atributo, ou seja, seu valor? Veremos como proteger a criação do atributo mais adiante.
O curso Python 3: avançando na orientação a objetos possui 159 minutos de vídeos, em um total de 62 atividades. Gostou? Conheça nossos outros cursos de Python em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Mais de 1200 cursos completamente atualizados, com novos lançamentos todas as semanas, em Programação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.
Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.
Emitimos certificados para atestar que você finalizou nossos cursos e formações.
Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.
Mais de 1200 cursos completamente atualizados, com novos lançamentos todas as semanas, em Programação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.
Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.
Emitimos certificados para atestar que você finalizou nossos cursos e formações.
Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.
Acesso completo
durante 1 ano
Estude 24h/dia
onde e quando quiser
Novos cursos
todas as semanas