Revisão de Programação Orientada a Objetos
---
id: 67f39dac6c3fac29c3d54918
title: Revisão de Programação Orientada a Objetos
challengeType: 31
dashedName: review-object-oriented-programming
---
# --description--
O que é Programação Orientada a Objetos?
- Programação orientada a objetos: Um estilo de programação no qual os desenvolvedores tratam tudo no seu código como um objeto do mundo real. É popularmente chamada de OOP. Os quatro princípios-chave que ajudam você a organizar e gerenciar o código de forma eficaz são encapsulamento, herança, polimorfismo e abstração
- Classes: O modelo para criar objetos. Cada objeto criado a partir de uma classe possui atributos que definem dados e métodos que determinam os comportamentos dos objetos.
O que é Encapsulamento?
- Encapsulamento: A agregação dos atributos e métodos de um objeto em uma única unidade. Isso permite ocultar o estado interno do objeto atrás de um conjunto simples de métodos e atributos públicos que funcionam como portas. Por trás dessas portas estão atributos e métodos privados que controlam como os dados mudam e quem pode vê-los.
- Exemplo de Encapsulamento: Se você quiser acompanhar o saldo da carteira, permitirá depósito e saque, mas não desejará que ninguém altere o próprio saldo da carteira:
class Wallet:
def __init__(self, balance):
self.__balance = balance # Private attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount # Add to the balance safely
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount # Remove from the balance safely
account = Wallet(500)
print(account.__balance) # AttributeError: 'Wallet' object has no attribute '__balance'
- Diferença Entre Prefixar Atributos com Underscore Simples e Duplo: Prefixar atributos e métodos com um underscore simples significa que eles são destinados para uso interno. Isso é uma convenção e não impede o acesso aos atributos de fora. Prefixar atributos e métodos com um underscore duplo efetivamente impede que eles sejam acessados de fora da sua classe.
O que são Getters e Setters?
- Getters e Setters: Métodos que permitem controlar como os atributos de uma classe são acessados e modificados. Você recupera valores com getters e define valores com setters.
- Propriedades: Elas conectam getters e setters e permitem o acesso a dados. Elas executam lógica extra nos bastidores quando você obtém, define ou exclui valores.
- Por que Propriedades em vez de Métodos: Propriedades são usadas em vez de métodos para melhor legibilidade e código mais limpo. Elas permitem que você acesse valores com notação de ponto, como atributos regulares, sem parênteses.
- Criando um Getter: Para criar um getter, você usa o decorador
@property. Aqui está um getter que obtém o raio de um círculo:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self): # A getter to get the radius
return self._radius
@property
def area(self): # A getter to calculate area
return 3.14 * (self._radius ** 2)
my_circle = Circle(3)
print(my_circle.radius) # 3
print(my_circle.area) # 28.26
- Criando um Setter: Para criar o setter que definirá o raio, você precisa definir outro método com o mesmo nome e usar
@<property_name>.setteracima dele:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self): # A getter to get the radius
return self._radius
@radius.setter
def radius(self, value): # A setter to set the radius
if value <= 0:
raise ValueError('Radius must be positive')
self._radius = value
my_circle = Circle(3)
print('Initial radius:', my_circle.radius) # Initial radius: 3
my_circle.radius = 8
print('After modifying the radius:', my_circle.radius) # After modifying the radius: 8
- Como o Python Lida com Getters e Setters: Depois que você define getters e setters, o Python os chama automaticamente nos bastidores sempre que você usa a sintaxe normal de atributo desta forma:
my_circle.radius # This will call the getter
my_circle.radius = 4 # This will call the setter
Ao definir um valor, você não deve atribuir ao próprio nome da propriedade porque isso causará um RecursionError. Use um nome interno separado, frequentemente com um underscore, para armazenar o valor.
- Deleter: Depois de definir e obter um valor com setter e getter, você pode controlar como ele é deletado com um
deleter. Um deleter executa uma lógica personalizada quando você usa a instruçãodelem uma propriedade. Para criar um deleter, você usa o decorador@<property_name>.deleter.
# Deleter
@radius.deleter
def radius(self):
print("Deleting radius...")
del self._radius
O que é Herança e Como Ela Promove a Reutilização de Código?
- Herança: O processo pelo qual uma classe filha usa os atributos e métodos de uma classe pai. A herança promove a reutilização de código, fornece hierarquias claras e personaliza o comportamento sem reescrever tudo. Para implementar a herança, uma classe filha recebe o nome de uma classe pai:
class Parent:
# Parent attributes and methods
class Child(Parent):
# Child inherits, extends, and/or overrides where necessary
- Herança Simples e Múltipla: Quando uma classe filha herda propriedades e métodos de um único pai, como você pode ver acima, o processo é chamado de herança simples. Quando uma classe filha herda propriedades e métodos de mais de um pai, isso é herança múltipla. Aqui está a sintaxe para isso:
class Parent:
# Attributes and methods for Parent
class Child:
# Attributes and methods for Child
class GrandChild(Parent, Child):
# GrandChild inherits from both Parent and Child
# GrandChild can combine or override behavior from each
- Função
super(): Uma função que permite você chamar um método de uma classe pai, quando uma classe tem uma implementação diferente desse método, ou estende o método, sem duplicar código.
O que é Polimorfismo e Como Ele Promove a Reutilização de Código?
- Polimorfismo: O princípio da POO que permite que diferentes classes usem o mesmo nome de método, mas cada classe o implemente de forma diferente quando chamado. Aqui está a sintaxe para isso:
class A:
def action(self): ...
class B:
def action(self): ...
class C:
def action(self): ...
Class().method() # Works for A, B, or C
- Polimorfismo baseado em herança: Um pai configura um método e cada classe filha o adapta para seu uso.
O que é Name Mangling e Como Ele Funciona?
- Name Mangling: Um processo no qual o Python renomeia internamente um atributo prefixado com dois underscores adicionando um underscore e o nome da classe como prefixo, transformando
__attributeem_ClassName__attribute. - O Propósito do Name Mangling: O principal propósito do name mangling é prevenir a sobrescrição acidental de atributos e métodos quando você usa herança. Aqui está um código que torna isso mais compreensível:
class Parent:
def __init__(self):
self.__data = 'Parent data'
class Child(Parent):
def __init__(self):
super().__init__()
self.__data = 'Child data'
c = Child()
print(c.__dict__) # {'_Parent__data': 'Parent data', '_Child__data': 'Child data'}
O que é Abstração e Como Ela Ajuda a Manter Sistemas Complexos Organizados?
- Abstração: Um conceito de programação no qual detalhes complexos de implementação de um objeto ou sistema são ocultados e apenas as funcionalidades essenciais são mostradas. Em Python e outras linguagens de programação, a abstração simplifica sistemas complexos aumentando a reutilização.
- Exemplo de Abstração: Um bom exemplo de abstração no dia a dia é um carro que permite que você use apenas o volante, os pedais e o câmbio sem saber como o
engineou osbrakesfuncionam. - Como o Python Implementa Abstração: Python implementa abstração através do módulo
abc. O módulo fornece a classeABC(abstract base class) e o decorador@abstractmethod. Uma abstract base class (ABC) define os métodos e propriedades comuns que as subclasses devem implementar. Ela não pode ser instanciada. - Como o Método Abstrato é Definido: Um método abstrato é definido com
@abstractmethode deve ser sobrescrito nas subclasses, mesmo que tenha uma implementação padrão. A sintaxe básica da abstração é assim:
from abc import ABC, abstractmethod
# Define an abstract base class
class AbstractClass(ABC):
@abstractmethod
def abstract_method(self):
pass
# Concrete subclass that implements the abstract method
class ConcreteClassOne(AbstractClass):
def abstract_method(self):
print('Implementation in ConcreteClassOne')
# Another concrete subclass
class ConcreteClassTwo(AbstractClass):
def abstract_method(self):
print('Implementation in ConcreteClassTwo')
# --assignment--
Revise os tópicos e conceitos de Programação Orientada a Objetos.