8

5 minutos: Aprenda orientação a objetos

#Python
André Vicente
André Vicente

Não sei por qual motivo sempre complicam POO.

Tentarei explicar de forma simples, por meio de analogias, e espero que ao final deste artigo você compreenda:

  • Classes
  • Objetos
  • Propriedades/Atributos
  • Métodos
  • Herança
  • Classe abstrata
  • Polimorfismo


Classes

São estruturas genéricas para definir coisas diversas. Imagine uma classe Pessoa, por exemplo. Você sabe diferenciar uma pessoa de um carro, por exemplo. Mas eu não disse uma pessoa em específico. Pessoa é genérico, pode ser qualquer uma.


Objetos

São instâncias de uma classe. Eu e você somos Pessoas, correto? Mas somos Pessoas diferentes. Eu sou eu, você é você. Cada objeto é específico. Isso que difere a classe do objeto.


Propriedades

São valores que um objeto possui. Por exemplo, todas as pessoas possuem uma altura. Logo, altura é uma propriedade definida dentro da classe Pessoa. Entretanto, sua altura é diferente da minha. Logo, a definição dos atributos é feita na classe, mas a valoração deles é feita no objeto. No código, uma propriedade é basicamente uma variável definida dentro de uma classe.


Métodos

São similares às propriedades, com a diferença que ao invés de substantivos, são verbos. Por exemplo, falar é um método da classe Pessoa, pois pessoas, em grande maioria, falam. Apesar disso, cada pessoa (ou seja, cada objeto) pode falar de uma forma diferente (por exemplo eu posso falar em um idioma e você em outro).


Exemplo em Python

class Pessoa:

    # ? A função __init__ roda toda vez que criamos uma nova pessoa

    def __init__(self, novo_nome, nova_altura):

        # ? self indica o objeto. Cada objeto vai ter um nome e uma altura

        self.nome = novo_nome

        self.altura = nova_altura


    # ? Aqui temos um método

    def crescer(self):

        crescimento = self.altura * 0.1

        self.altura += crescimento

        print(f"{self.nome} cresceu {crescimento}cm.")



eu = Pessoa("André", 150)  # ? Objeto eu da classe Pessoa

você = Pessoa("Fulano", 180)  # ? Objeto você da classe Pessoa

print(eu.nome)  # ? Meu nome

print(você.nome)  # ? É diferente do seu

# ? Mas nós dois temos nome, pois nós dois somos pessoas

eu.crescer()  # ? Eu posso crescer, pois sou uma pessoa

você.crescer()  # ? VocÊ também pode crescer, mas vai ser diferente de mim


O resultado do código acima é

André

Fulano

André cresceu 15.0cm.

Fulano cresceu 18.0cm.


Síntese intermediária

Com base nessas definições acima você já deve entender parte da utilidade da POO.

Se eu pretendo usar uma mesma estrutura lógica (uma classe Pessoa) para criar diversas variáveis (vários indivíduos diferentes) que podem ter as mesmas propriedades (altura, peso, etc), apesar de os valores serem diferentes (minha altura é diferente da sua), fazer as mesmas coisas (falar, comer, etc), apesar de a forma ser diferente (eu falo em um idioma, você em outro), eu simplifico a criação de estruturas genéricas e que eu posso usar em vários projetos.


Herança

São classes que herdam as características de outras e diferem destas se especializando. Como não é legal separar as pessoas, vamos a um exemplo diferente. Imagine que você tem uma classe chamada Carro. Lembrando, a classe é genérica, quando eu digo "Carro", não estou especificando. Os objetos podem ser o carro de fulano, o carro de siclano, etc. Bom, faz sentido dizer que todos os carros têm algo em comum, correto? Para fins didáticos, todos têm um volante, todos têm 4 rodas, etc. Mas existem alguns carros com diferenças muito grandes para que você considere eles simplesmente como um Carro, ainda que eles o sejam. Por exemplo, posso dividir em 2, um Carro Elétrico e um Carro a Combustão. Concorda comigo que são muitas semelhanças para criar classes completamente diferentes, mas são muitas diferenças para criar classes iguais. O que fazer? Simples! Cria 3 classes. Carro, que conterá todas as partes em comum, como as rodas e volante, por exemplo; Carro Elétrico, que irá herdar todas as coisas da classe Carro, ou seja, ele também terá rodas e volante, mas terá coisas a mais (que o carro a combustão não tem), como por exemplo um motor específico; e por último, Carro a Combustão, que também irá herdar de Carro, ter volante e rodas, mas terá coisas a mais (que o carro elétrico não tem), como por exemplo o motor específico.

Basicamente com a herança você cria tudo que é comum (rodas, volante) uma vez só, e distribui para n classes filhas, para que elas possam se especializar (criar coisas que só elas têm, e as irmãs não).


Classe abstrata

São classes que não instanciam objetos. Pense no exemplo anterior. Temos 3 classes: Carro, Carro Elétrico e Carro a Combustão. Supondo que só existam os dois últimos tipos de carro no mundo, concorda comigo que todo carro que eu criar ou será elétrico ou será a combustão? Então eu só vou instanciar carros elétricos e carros a combustão, mas não vou instanciar nenhum objeto da classe Carro. Apesar disso, a classe Carro é usada pelas suas classes filhas, então eu não posso simplesmente apagar ela. Por isso chamamos ela de classe abstrata. Ela existe para ter classes filhas, mas não para instanciar objetos.


Polimorfismo

São métodos com a mesma assinatura, mas que se comportam de formas diferentes. Como assim? Eu explico. Mas antes, saliento que existem várias formas de polimorfismo. Irei explicar somente o conceito: Concorda comigo que nenhum carro possui energia infinita, correto? Então todos os carros precisam ter um método para suprir a energia. Vamos chamar este método de abastecer. Hora, se todo carro precisa abastecer, então abastecer deve ser um método da classe Carro, ok? Sim. Mas você concorda também que o Carro Elétrico vai ser abastecido de forma diferente do Carro a Combustão, ok? O primeiro vai ser abastecido com energia elétrica da tomada, enquanto o segundo com algum combustível num posto de gasolina. Logo, apesar de ambos serem carros, e ambos possuírem o método abastecer, cada um vai executar esse método de uma forma diferente. Isso é uma forma de polimorfismo. No código, de fato o método abastecer existe na classe Carro, mas ele não é implementado nela (você declara a função, mas não coloca nada dentro dela). Você implementa mesmo é em cada uma das classes filhas, com suas especificidades.


Exemplo em Python

# ? Classe abstrata

class Carro:

    # ? Sempre que criar um novo carro (objeto)

    def __init__(self):

        # ? Ele vai ter 4 rodas

        self.rodas = 4


    def abastecer(self):

        print("O carro está abastecendo!")



class CarroElétrico(Carro):  # ? Herda da classe carro

    def __init__(self):

        super().__init__()  # ? Inicializa com os atributos da classe pai


    # ? Polimorfismo, ou sobrecarga de método

    def abastecer(self):

        super().abastecer()

        print("Como é um carro elétrico, está na tomada.")



class CarroACombustão(Carro):

    def __init__(self):

        super().__init__()


    def abastecer(self):

        super().abastecer()

        print("Como é um carro a combustão, está no posto de gasolina.")



c1 = CarroElétrico()

c2 = CarroACombustão()

print(f"O Carro 1 tem {c1.rodas} rodas.")

print(f"O Carro 2 tem {c2.rodas} rodas.")

c1.abastecer()

c2.abastecer()


O resultado do código acima é

O Carro 1 tem 4 rodas.

O Carro 2 tem 4 rodas.

O carro está abastecendo!

Como é um carro elétrico, está na tomada.

O carro está abastecendo!

Como é um carro a combustão, está no posto de gasolina.


Conclusão

Espero que agora você tenha compreendido a simplicidade teórica da orientação a objetos. Nada daquele bicho de 7 cabeças que dizem por aí, né? Agora implementar isso em código pode não ser tão simples, e varia de linguagem pra linguagem.


O que achou? Alguma dúvida? Algo errado? Algo a acrescentar? Comenta aí! =D


Edit: Adicionei exemplos em Python

4
81

Comentários (4)

1
Santiago Souto

Santiago Souto

16/12/2020 00:39

Poxa André brigado me ajudou para caramba, ainda não tinha entendido poo direito mas agora com essa sua explicação clareou muito minhas ideias!!

1
Adriana Silva

Adriana Silva

13/12/2020 13:23

André, seu artigo ficou muito bom!


A primeira frase "Não sei por qual motivo sempre complicam POO" é algo que sempre ficou na minha mente. Obrigada pelos exemplos e acredito que sua explicação ajudar muita gente!


Parabéns e continue compartilhando seus conhecimentos :)

2
Norberto Celestino

Norberto Celestino

12/12/2020 14:09

Olá, André!


Desde já eu lhe agradeço, pois, sua explicação ficou simples e clara para meu entendimento. Se você puder colocar um código de exemplo, acho que ficaria muito bom o seu conteúdo com a prática.


Valeu e abraço. ;)

1
André Vicente

André Vicente

13/12/2020 03:00

Coloquei alguns exemplos em Python!

None

Brasil