Aprenda Python

  • Página Inicial
  • Contato!
  • Tudo sobre Python Parte 1!
  • Tudo sobre Python Parte 2!
  • Tudo sobre Python Parte 3!
  • Tudo sobre Python Parte 4!
  • Tudo sobre Python Parte 5!
  • Tudo sobre Python Parte 6!
  • Tudo sobre Python Parte 7!
  • Introdução ao POO em Python

    Criando Classes e Objetos

    Criação de classe (atributos com __ são privados):

    
    class Caneta:
        __modelo = ""
        __cor = ""
        __ponta = 0
        __tampada = False
    
        def tampar(self):
            self.__tampada = True
    
        def destampar(self):
            self.__tampada = False
    
        def status(self):
            print("Modelo: {}".format(self.__modelo))
            print("Cor: {}".format(self.__cor))
            print("Ponta: {}".format(self.__ponta))
            print("Tampada: {}".format(self.__tampada))
    
    
    

    Instanciação básica:

    
    c1 = Caneta()
    
    c1.status()
    
    

    Quando criamos uma classe, temos mais trabalho para fazê-la, mas depois que ela está pronta, podemos criar quantos objetos precisarmos vindos dessa mesma classe, e o programa principal fica mais simples, menor e mais natural. Os objetos criados dessa mesma classe são independentes entre si e o status de um não interfere no outro. Essa é uma das vantagens da orientação a objetos.

    PS: Para pegar o nome da classe, use self.__class__.__name__.

    Encapsulamento e Construtor e Métodos Estáticos

    Classe com getters, setters, construtor e destrutor:

    
    class Caneta:
        __modelo = ""
        __cor = ""
        __ponta = 0
        __tampada = False
    
        def tampar(self):
            self.__tampada = True
    
        def destampar(self):
            self.__tampada = False
    
        def status(self):
            print("Modelo: {}".format(self.__modelo))
            print("Cor: {}".format(self.__cor))
            print("Ponta: {}".format(self.__ponta))
            print("Tampada: {}".format(self.__tampada))
    
        # Construtor
        def __init__(self, m, c, p):
            self.__modelo = m
            self.__cor = c
            self.__ponta = p
            self.tampar()
    
        # Destrutor
        def __del__(self):
            print("Objeto Caneta Destruído com Sucesso!")
    
        def getModelo(self):
            return self.__modelo
    
        def getPonta(self):
            return self.__ponta
    
        def setModelo(self, modelo):
            self.__modelo = modelo
    
        def setPonta(self, ponta):
            self.__ponta = ponta
    
    

    PS: Caso num construtor precise inicializar um atributo como nulo, use None.

    Uso:

    
    c1 = Caneta("BIC", "Azul", 0.4)
    c2 = Caneta("Pilot", "Verde", 1.0)
    
    c1.status()
    c2.status()
    
    del c1
    del c2 
    
    

    Veja um exemplo de classe somente com métodos e atributos estáticos:

    
    class Lampada:
        __preco = 9.50 # Simulação de estático
        __acesa = False
        
        @staticmethod
        def custo(): # Método estático não tem self, atributos também não
            print("A lâmpada custa R${:.2f}.".format(Lampada.__preco))
        
        @staticmethod
        def acender():
            print("A lâmpada está acesa!")
            Lampada.__acesa = True
        
        @staticmethod
        def apagar():
            print("A lâmpada está apagada!")
            Lampada.__acesa = False
    
    

    E o uso:

    
    from Lampada import Lampada
    
    Lampada.custo() # Método estático.
    
    Lampada.acender()
    Lampada.apagar()
    
    Lampada.__custo = 8.25 # Atributo estático
    
    

    PS: Métodos estáticos só podem trabalhar outros métodos e atributos quando estes também forem estáticos, e não podem ser sobrepostos. E atributos estáticos é recomendável eles serem inicializados.

    Abstração

    Simulação de interface com classe só com método abstratos:

    
    from abc import ABC, abstractmethod
    
    class Controlador(ABC):
        @abstractmethod
        def ligar(self):
            pass
    
        @abstractmethod
        def desligar(self):
            pass
    
        @abstractmethod
        def abrirMenu(self):
            pass
    
        @abstractmethod
        def fecharMenu(self):
            pass
    
        @abstractmethod
        def maisVolume(self):
            pass
    
        @abstractmethod
        def menosVolume(self):
            pass
    
        @abstractmethod
        def play(self):
            pass
    
        @abstractmethod
        def pause(self):
            pass
    
    

    Classe herdeira:

    
    from Controlador import Controlador
    
    class ControleRemoto(Controlador):
        __volume = 0
        __ligado = False
        __tocando = False
    
        def ligar(self):
            self.setLigado(True)
    
        def desligar(self):
            self.setLigado(False)
    
        def abrirMenu(self):
            print("Está ligado? {}".format(self.getLigado()))
            print("Está tocando? {}".format(self.getTocando()))
            print("Volume: {}".format(self.getVolume()), end="")
    
            for i in range(0, self.getVolume() + 1, 2):
                print("|", end="")
    
            print("")
    
        def fecharMenu(self):
            print("Fechando Menu...")
    
        def maisVolume(self):
            if self.getLigado():
                if self.getVolume() < 100:
                    self.setVolume(self.getVolume() + 2)
            else:
                print("ERRO! Está Desligado, Não Posso Aumentar o Volume!")
    
        def menosVolume(self):
            if self.getLigado():
                if self.getVolume() > 0:
                    self.setVolume(self.getVolume() - 2)
            else:
                print("ERRO! Está Desligado, Não Posso Diminuir o Volume!")
    
        def play(self):
            if self.getLigado() and not self.getTocando():
                self.setTocando(True)
    
        def pause(self):
            if self.getLigado() and self.getTocando():
                self.setTocando(False)
    
        def __init__(self):
            self.__volume = 50
            self.__ligado = False
            self.__tocando = False
    
        def __del__(self):
            print("Objeto ControleRemoto Destruído com Sucesso!")
    
        def getVolume(self):
            return self.__volume
    
        def getLigado(self):
            return self.__ligado
    
        def getTocando(self):
            return self.__tocando
    
        def setVolume(self, volume):
            self.__volume = volume
    
        def setLigado(self, ligado):
            self.__ligado = ligado
    
        def setTocando(self, tocando):
            self.__tocando = tocando
    
    

    Instanciação:

    
    from ControleRemoto import ControleRemoto
    
    c = ControleRemoto()
    
    c.ligar()
    c.maisVolume()
    c.abrirMenu()
    
    del c
    
    

    PS: Ao chamar métodos da classe pai na classe filha, use o método super() seguido do nome do método, como super().__init__() (no caso do construtor), pode ser feito com qualquer método. Caso precise atribuir valor nulo à algum atributo ou variável, use None.

    Herança e Polimorfismo

    Exemplo com herança e polimorfismo:

    
    from abc import ABC, abstractmethod
    
    class Mamifero(ABC):
        @abstractmethod
        def lutar(self):
            pass
    
        def respirar(self):
            print("Eu Respiro!")
    
        def mamar(self):
            print("Eu Mamo!")
    
    

    Classe herdeira:

    
    from Mamifero import Mamifero
    
    class Gato(Mamifero):
        # Sobrescrevendo método abstrato
        def lutar(self):
            print("Gatos Lutam Arranhando!")
    
        def arranhar(self):
            print("Eu Arranho!")
    
    

    Outra classe herdeira:

    
    from Mamifero import Mamifero
    
    class Humano(Mamifero):
        # Sobrescrevendo método abstrato
        def lutar(self):
            print("Humanos Lutam com Armas!")
    
        def falar(self):
            print("Eu Falo!")
    
    

    E a implementação:

    
    from Gato import *
    from Humano import *
    
    bicho = Mamifero() # Dará erro por ser abstrata
    homem = Humano()
    bichano = Gato()
    
    homem.falar()
    homem.respirar()
    homem.lutar()
    
    bichano.arranhar()
    bichano.respirar()
    bichano.lutar()
    
    

    PS: O Python permite herança múltipla, no caso, separe as classes pai por virgulas, como class NomeClasseFilha(NomeClassePai1, NomeClassePai2):.

    Agregação de Objetos

    Vamos supor essa classe:

    
    class Pilha:
        __marca = ""
        __carga = 0
    
        def __init__(self, marca):
             self.__marca = marca
             self.__carga = 100
    
        def apresentacao(self):
             print(f"A marca da pilha é {self.__marca}.")
             print(f"A carga da pilha é {self.__carga}%.")
    
        def getMarca(self):
            return self.__marca
    
        def getCarga(self):
            return self.__carga
    
        def setMarca(self, marca):
            self.__marca = marca
    
        def setCarga(self, carga):
            self.__carga = carga
    
    

    Nós podemos fazer relacionamentos entre classes diferentes, veja por exemplo a classe abaixo, que tem um atributo do "tipo" da classe acima:

    
    class Aparelho:
        __pl = None
    
        def __init__(self, pl):
            self.__pl = pl
    
        def __del__(self):
            del self.__pl
    
        def ligado(self):
            if self.__pl.getCarga() > 0: # Getter do objeto Pilha
                print(f"O aparelho está ligado e a carga da pilha é de {self.__pl.getCarga()}%!")
            else:
                print("A pilha do aparelho está sem carga!")
    
        def getPl(self):
            return self.__pl
    
        def setPl(self, pl):
            self.__pl = pl
    
    

    Aí podemos chamar os objetos assim:

    
    ray = Pilha("Rayovac")
    
    ray.apresentacao()
    
    controle = Aparelho(ray)
    
    controle.ligado()
    
    print(f"A carga da pilha é de {controle.getPl().getCarga()}%!")