Exercícios da Semana 02: POO

Desafios de refatoração, validação e propriedades em Python.

O Que Você Vai Aprender

Nesta sessão de exercícios, você aplicará os conceitos de encapsulamento, modificadores de acesso (conveção em Python) e propriedades para refatorar classes e garantir a integridade dos dados.

🔒 Refatorar Atributos

Transformar atributos de público para protegido ou privado.

✅ Implementar Validação

Adicionar lógica para garantir a validade das operações.

✨ Usar Propriedades

Aplicar `@property` e `@setter` para controle de acesso elegante.

Exercícios 1 & 2: `ContaBancaria` Refatorada e Validada

**1. Refatore a classe `ContaBancaria`** para que o saldo seja um atributo protegido (`_saldo`) ou privado (`__saldo`).
**2. Garanta que não seja possível depositar um valor negativo ou sacar mais do que o saldo disponível.**

Solução Proposta para `ContaBancaria`

class ContaBancaria:
    def __init__(self, titular, saldo_inicial=0.0):
        self.titular = titular
        self._saldo = saldo_inicial # Atributo protegido

    def depositar(self, valor):
        if valor > 0:
            self._saldo += valor
            print(f"Depósito de R${valor:.2f} realizado com sucesso.")
            print(f"Novo saldo: R${self._saldo:.2f}")
        else:
            print("Valor de depósito inválido. O valor deve ser positivo.")

    def sacar(self, valor):
        if valor > 0 and self._saldo >= valor:
            self._saldo -= valor
            print(f"Saque de R${valor:.2f} realizado com sucesso.")
            print(f"Novo saldo: R${self._saldo:.2f}")
        elif valor <= 0:
            print("Valor de saque inválido. O valor deve ser positivo.")
        else:
            print(f"Saldo insuficiente para sacar R${valor:.2f}. Saldo atual: R${self._saldo:.2f}")

    def get_saldo(self): # Getter simples para visualização (opcional)
        return self._saldo

# Exemplo de uso:
# minha_conta = ContaBancaria("João", 1000.0)
# minha_conta.depositar(500.0)
# minha_conta.sacar(200.0)
# minha_conta.sacar(1500.0) # Saque insuficiente
# minha_conta.depositar(-100.0) # Valor inválido

Simulador: Operações na `ContaBancaria`

Interaja com uma conta de exemplo para testar depósitos e saques com validação. Saldo atual: R$ 1000.00

Exercício 3: Classe `Retangulo` com Propriedades

Crie uma classe `Retangulo` com atributos privados `_largura` e `_altura`. Use propriedades (`@property` e `@.setter`) para garantir que eles nunca recebam valores negativos. Crie uma propriedade somente leitura `area` que calcula a área do retângulo.

Solução Proposta para `Retangulo`

class Retangulo:
    def __init__(self, largura, altura):
        self._largura = 0 # Inicializa com valor padrão
        self._altura = 0  # Inicializa com valor padrão
        self.largura = largura # Usa o setter da propriedade
        self.altura = altura   # Usa o setter da propriedade

    @property
    def largura(self):
        return self._largura

    @largura.setter
    def largura(self, nova_largura):
        if nova_largura >= 0:
            self._largura = nova_largura
        else:
            print("Erro: Largura não pode ser negativa.")

    @property
    def altura(self):
        return self._altura

    @altura.setter
    def altura(self, nova_altura):
        if nova_altura >= 0:
            self._altura = nova_altura
        else:
            print("Erro: Altura não pode ser negativa.")

    @property # Propriedade somente leitura
    def area(self):
        return self._largura * self._altura

# Exemplo de uso:
# ret = Retangulo(10, 5)
# print(f"Largura: {ret.largura}, Altura: {ret.altura}")
# print(f"Área: {ret.area}")

# ret.largura = -2 # Erro: Largura não pode ser negativa.
# ret.altura = 8
# print(f"Nova Área: {ret.area}")

Simulador: `Retangulo` com Propriedades

Defina a largura e altura do retângulo e calcule a área. Largura: 0, Altura: 0