Este repositório contém uma série de exercícios práticos de Programação Orientada a Objetos (POO) em Python, desenvolvidos no contexto de uma Escola de Ensino Superior.
Proporcionar aos estudantes uma experiência prática e progressiva dos conceitos fundamentais de POO através de exercícios que simulam situações reais de uma instituição de ensino.
- Classe: Um modelo ou template que define a estrutura e comportamento de objetos. É como um "molde" que especifica quais atributos (dados) e métodos (funções) os objetos terão.
- Objeto: Uma instância específica de uma classe. É a materialização concreta do modelo definido pela classe.
- Instanciação: O processo de criar um objeto a partir de uma classe usando o operador de chamada
().
- Método
__init__(): Método especial chamado automaticamente quando um objeto é criado. Responsável por inicializar os atributos do objeto. - Parâmetros do Construtor: Valores passados durante a criação do objeto para configurar seu estado inicial.
- Self: Referência ao próprio objeto, usado para acessar atributos e métodos da instância.
- Atributos de Instância: Variáveis que pertencem a cada objeto específico, definidas com
self.atributo. - Atributos de Classe: Variáveis compartilhadas por todas as instâncias da classe.
- Métodos de Instância: Funções que operam sobre dados específicos de cada objeto.
- Métodos de Classe: Funções que operam sobre a classe como um todo, marcadas com
@classmethod. - Métodos Estáticos: Funções relacionadas à classe mas que não acessam dados da instância ou classe, marcadas com
@staticmethod.
O encapsulamento é um dos pilares fundamentais da POO que consiste em:
- Ocultar detalhes internos: Proteger dados e implementação interna da classe
- Controlar acesso: Definir como os dados podem ser acessados e modificados
- Manter integridade: Garantir que o objeto sempre esteja em um estado válido
- Público: Atributos e métodos acessíveis de qualquer lugar (
atributo) - Protegido: Convenção para indicar uso interno, prefixo
_(_atributo) - Privado: Dificultam acesso externo, prefixo
__(__atributo)
- @property: Decorator que permite acessar métodos como se fossem atributos
- Getter: Método para obter o valor de um atributo privado
- Setter: Método para definir o valor de um atributo com validação
- Validação de Dados: Verificações realizadas antes de alterar o estado do objeto
- Classe Base (Pai/Superclasse): Classe que define características comuns
- Classe Derivada (Filha/Subclasse): Classe que herda e especializa a classe base
- Relação "é um": A herança representa uma relação hierárquica onde a subclasse "é um" tipo da superclasse
- Herança Simples: Uma classe herda de apenas uma classe pai
- Herança Múltipla: Uma classe herda de múltiplas classes pai (suportada em Python)
- Método super(): Função que permite chamar métodos da classe pai
- Sobrescrita de Métodos: Redefinição de métodos herdados para comportamento específico
- Extensão de Funcionalidade: Adicionar novos métodos e atributos às classes filhas
- Polimorfismo: Capacidade de objetos de diferentes classes responderem à mesma interface de forma específica
- Polimorfismo de Sobrescrita: Mesmo método implementado diferentemente em classes relacionadas por herança
- Polimorfismo de Interface: Objetos não relacionados que implementam os mesmos métodos
- Flexibilidade: Código que funciona com diferentes tipos de objetos
- Extensibilidade: Facilita adição de novos tipos sem modificar código existente
- Manutenibilidade: Reduz acoplamento entre componentes do sistema
- Definição: Relacionamento "tem um" onde um objeto contém outros objetos como partes integrantes
- Ciclo de Vida: Os objetos componentes dependem do objeto principal
- Exemplo: Um Carro "tem um" Motor - se o carro é destruído, o motor também é
- Definição: Relacionamento "usa um" onde objetos existem independentemente mas se referenciam
- Ciclo de Vida: Os objetos podem existir separadamente
- Exemplo: Um Professor "leciona para" Alunos - professor e alunos existem independentemente
- Definição: Múltiplos objetos de um tipo se relacionam com múltiplos objetos de outro tipo
- Implementação: Geralmente usando listas ou conjuntos para armazenar referências
- Exemplo: Alunos podem estar matriculados em várias Disciplinas, e cada Disciplina pode ter vários Alunos
- Propósito: Métodos que operam sobre a classe, não sobre instâncias específicas
- Primeiro Parâmetro:
cls(referência à classe) - Uso Comum: Factory methods (métodos fábrica) para criar objetos de formas específicas
- Acesso: Podem ser chamados tanto pela classe quanto por instâncias
- Propósito: Funções relacionadas à classe mas que não precisam acessar dados da classe ou instância
- Parâmetros: Não recebem
selfnemclsautomaticamente - Uso Comum: Funções utilitárias relacionadas ao domínio da classe
- Acesso: Podem ser chamados pela classe ou instâncias, mas funcionam como funções normais
- Definição: Uma classe deve ter apenas uma razão para mudar
- Objetivo: Cada classe deve ter uma única responsabilidade
- Benefícios: Código mais coeso, fácil manutenção e teste
- Definição: Aberto para extensão, fechado para modificação
- Objetivo: Adicionar funcionalidades sem alterar código existente
- Implementação: Uso de abstrações e polimorfismo
- Definição: Objetos de subclasses devem substituir objetos da superclasse
- Objetivo: Manter comportamento consistente na hierarquia
- Regra: Subclasses não devem quebrar contratos da classe base
- Definição: Clientes não devem depender de interfaces que não usam
- Objetivo: Interfaces pequenas e específicas
- Benefícios: Menor acoplamento e maior flexibilidade
- Definição: Depender de abstrações, não de implementações
- Objetivo: Reduzir acoplamento entre módulos
- Técnica: Injeção de dependência
- Adapter: Permite que interfaces incompatíveis trabalhem juntas
- Decorator: Adiciona comportamentos a objetos dinamicamente
- Facade: Fornece interface simplificada para subsistema complexo
- Observer: Define dependência um-para-muitos entre objetos
- Strategy: Encapsula algoritmos e os torna intercambiáveis
| Exercício | Conceito Principal | Descrição | Link |
|---|---|---|---|
| 01 | Modelagem Básica | Criação de classes simples (Aluno, Disciplina) | Exercício 01 |
| 02 | Métodos e Comportamento | Adição de métodos para manipular estado | Exercício 02 |
| 03 | Encapsulamento | Atributos privados e properties | Exercício 03 |
| 04 | Herança Simples | Classes base e derivadas | Exercício 04 |
| 05 | Herança com super() | Uso correto de super() em construtores | Exercício 05 |
| 06 | Composição | Relacionamento "tem um" entre objetos | Exercício 06 |
| 07 | Agregação N:N | Relacionamentos muitos-para-muitos | Exercício 07 |
| 08 | Métodos de Classe | Factory methods com @classmethod | Exercício 08 |
| 09 | Polimorfismo | Diferentes implementações do mesmo método | Exercício 09 |
| 10 | Jogo dos 7 Erros | Identificação e correção de erros comuns | Exercício 10 |
| Exercício | Princípio | Descrição | Link |
|---|---|---|---|
| 11 | SRP - Responsabilidade Única | Separação de responsabilidades em classes | Exercício 11 |
| 12 | OCP - Aberto/Fechado | Extensão sem modificação | Exercício 12 |
| 13 | LSP - Substituição de Liskov | Substituição de objetos sem quebrar funcionalidade | Exercício 13 |
| 14 | ISP - Segregação de Interface | Interfaces específicas e coesas | Exercício 14 |
| 15 | DIP - Inversão de Dependência | Dependência de abstrações | Exercício 15 |
| Exercício | Padrão | Descrição | Link |
|---|---|---|---|
| 16 | Adapter (Estrutural) | Integração de interfaces incompatíveis | Exercício 16 |
| 17 | Decorator (Estrutural) | Adição dinâmica de funcionalidades | Exercício 17 |
| 18 | Facade (Estrutural) | Simplificação de interface complexa | Exercício 18 |
| 19 | Observer (Comportamental) | Notificação de mudanças de estado | Exercício 19 |
| 20 | Strategy (Comportamental) | Alternância de algoritmos dinamicamente | Exercício 20 |
Todos os exercícios são baseados em entidades e situações de uma escola de ensino superior:
- Aluno: Matrícula, notas, disciplinas
- Professor: Salário, departamento, disciplinas
- Funcionário: Cargo, salário, dados pessoais
- Disciplina: Código, carga horária, alunos matriculados
- Curso: Disciplinas, carga horária total
- Departamento: Professores, área de atuação
- Secretaria: Gerenciamento de matrículas
- Fork este repositório: Clique em "Fork" no GitHub para criar sua cópia
- Clone seu fork:
https://github.com/AleTavares/poo-python-exercises.git - Leia o exercício: Cada arquivo
.mdcontém a descrição detalhada - Implemente sua solução: Crie o arquivo Python solicitado
- Teste localmente: Execute e verifique se atende aos requisitos
- Commit e push: Envie suas alterações para seu fork
- Abra um Pull Request: Submeta sua solução para correção automática
Antes de submeter sua solução, você pode executar os testes localmente para verificar se sua implementação está correta:
# Instale as dependências
pip install -r requirements.txt# Para testar apenas o exercício 1
python -m pytest tests/test_exercicio01.py -vpython -m pytest tests/test_exercicio02.py -v# Executa todos os testes do projeto
python -m pytest tests/ -v- PASSED: Teste passou - sua implementação está correta
- FAILED: Teste falhou - verifique a mensagem de erro
- ERROR: Erro de importação - verifique o nome do arquivo
tests/test_exercicio01.py::test_aluno_creation PASSED
tests/test_exercicio01.py::test_disciplina_creation PASSED
tests/test_exercicio01.py::test_aluno_attributes PASSED
tests/test_exercicio01.py::test_aluno_creation FAILED
E AttributeError: 'Aluno' object has no attribute 'nome'
Este repositório possui correção automática via GitHub Actions!
- Ao abrir um Pull Request, os testes são executados automaticamente
- Cada exercício é testado individualmente
- Resultado aparece como comentário no seu PR
- Feedback imediato sobre acertos e erros
Para que a correção automática funcione, nomeie seus arquivos corretamente:
respExercicio01.py- Exercício 1respExercicio02.py- Exercício 2respExercicio03.py- Exercício 3- ...
Resposta_10.py- Exercício 10 (Jogo dos 7 Erros)respExercicio11.py- Exercício 11 (SRP)- ...
respExercicio20.py- Exercício 20 (Strategy)
# 1. Fork e clone
git clone https://github.com/AleTavares/poo-python-exercises.git
cd poo-python-exercises
# 2. Crie uma branch para seu exercício
git checkout -b exercicio-01
# 3. Implemente sua solução
# Crie o arquivo respExercicio01.py
# 4. Commit e push
git add respExercicio01.py
git commit -m "Implementa exercício 01 - Modelagem Básica"
git push origin exercicio-01
# 5. Abra um Pull Request no GitHub
# A correção automática será executada!EngSoftPraticaPOO/
├── README.md # Este arquivo
├── .gitignore # Arquivos ignorados pelo Git
├── requirements.txt # Dependências Python
├── .github/
│ └── workflows/
│ └── test-exercises.yml # GitHub Actions
├── tests/
│ ├── test_exercicio01.py # Testes do exercício 1
│ ├── test_exercicio02.py # Testes do exercício 2
│ └── ... # Demais testes
├── exercicio_01.md # Exercício 1: Modelagem Básica
├── exercicio_02.md # Exercício 2: Métodos
├── exercicio_03.md # Exercício 3: Encapsulamento
├── exercicio_04.md # Exercício 4: Herança
├── exercicio_05.md # Exercício 5: super()
├── exercicio_06.md # Exercício 6: Composição
├── exercicio_07.md # Exercício 7: Agregação
├── exercicio_08.md # Exercício 8: @classmethod
├── exercicio_09.md # Exercício 9: Polimorfismo
├── exercicio_10.md # Exercício 10: Jogo dos 7 Erros
└── Arquivos de resposta # (Incluídos no .gitignore)
Os exercícios foram organizados em ordem crescente de complexidade:
- Básico (Ex. 1-3): Classes, objetos, encapsulamento
- Intermediário (Ex. 4-6): Herança, composição
- Avançado (Ex. 7-9): Relacionamentos complexos, polimorfismo
- Desafio (Ex. 10): Identificação e correção de erros
- SOLID (Ex. 11-15): Princípios de design orientado a objetos
- Design Patterns (Ex. 16-20): Padrões de projeto estruturais e comportamentais
Cada exercício possui testes automatizados que verificam:
- Existência das classes solicitadas
- Implementação dos métodos obrigatórios
- Funcionamento correto dos conceitos de POO
- Relacionamentos entre objetos
- Herança e polimorfismo adequados
- Encapsulamento correto
- Vermelho (Failed): Exercício com erros - verifique os logs
- Verde (Passed): Exercício aprovado - parabéns!
- Amarelo (Pending): Testes em execução - aguarde
- Pratique gradualmente: Não pule exercícios
- Entenda antes de implementar: Leia bem os requisitos
- Use a correção automática: Abra PRs para feedback imediato
- Analise os logs de teste: Eles mostram exatamente o que está faltando
- Refatore quando necessário: Melhore seu código após funcionar
- Use as convenções Python: PEP 8 para estilo de código
Este material foi desenvolvido para fins educacionais. Sugestões de melhorias são bem-vindas!
Para dúvidas sobre os exercícios:
- Consulte os logs dos testes no GitHub Actions
- Analise as mensagens de erro nos Pull Requests
- Revise a documentação oficial do Python
- Estude os conceitos teóricos de POO
- Compare com os exemplos nos arquivos
.md
- ImportError: Verifique o nome do arquivo
- AttributeError: Classe ou método não implementado
- AssertionError: Valor retornado diferente do esperado
- NameError: Variável ou classe não definida
Bons estudos!