Encapsulamento, Herança e Polimorfismo

Encapsulamento

Encapsulamento é um dos pilares fundamentais da Programação Orientada a Objetos (POO). Trata-se do princípio de esconder os detalhes internos de um objeto e expor apenas o necessário. Em Python, isso é geralmente feito através da definição de métodos de acesso (getters) e métodos de modificação (setters).

Exemplo Prático de Encapsulamento

Imaginemos que estamos a criar uma aplicação para gerir uma biblioteca. Teremos uma classe Livro que precisa de encapsular os detalhes sobre o título e o autor dos livros. Vamos começar por definir esta classe:

class Livro:
    def __init__(self, titulo, autor):
        self.__titulo = titulo
        self.__autor = autor

    def obter_titulo(self):
        return self.__titulo

    def definir_titulo(self, titulo):
        self.__titulo = titulo

    def obter_autor(self):
        return self.__autor

    def definir_autor(self, autor):
        self.__autor = autor

Neste exemplo, __titulo e __autor são atributos privados, indicados pela dupla underscore inicial. Os métodos obter_titulo, definir_titulo, obter_autor e definir_autor são os métodos de acesso e modificação.

Exemplo de Uso

livro1 = Livro("1984", "George Orwell")
print(livro1.obter_titulo())  # "1984"
print(livro1.obter_autor())   # "George Orwell"

livro1.definir_titulo("Animal Farm")
print(livro1.obter_titulo())  # "Animal Farm"

Herança

Herança permite que uma classe derive propriedades e métodos de outra classe. Isto ajuda na reutilização de código e na criação de uma estrutura hierárquica entre classes.

Exemplo Prático de Herança

Vamos ampliar o exemplo da biblioteca. Este sistema também vai gerir tipos de livros, como LivroDigital e LivroFisico. Ambas as classes vão herdar da classe base Livro.

class LivroDigital(Livro):
    def __init__(self, titulo, autor, tamanho_em_mb):
        super().__init__(titulo, autor)
        self.tamanho_em_mb = tamanho_em_mb

class LivroFisico(Livro):
    def __init__(self, titulo, autor, numero_de_paginas):
        super().__init__(titulo, autor)
        self.numero_de_paginas = numero_de_paginas

Exemplo de Uso

ebook = LivroDigital("Clean Code", "Robert C. Martin", 5)
print(ebook.obter_titulo())  # "Clean Code"
print(ebook.tamanho_em_mb)   # 5

livro_papel = LivroFisico("O Senhor dos Anéis", "J.R.R. Tolkien", 1200)
print(livro_papel.obter_titulo())     # "O Senhor dos Anéis"
print(livro_papel.numero_de_paginas)  # 1200

Polimorfismo

Polimorfismo permite que diferentes classes possam ser tratadas como instâncias da mesma classe através de uma interface comum. De forma simples, permite que um método possa fazer coisas diferentes consoante o objeto que o invoca.

Exemplo Prático de Polimorfismo

Continuando com o nosso exemplo da biblioteca, podemos ter um método que mostra informações sobre qualquer tipo de livro.

def mostrar_info_livro(livro):
    print(f"Título: {livro.obter_titulo()}")
    print(f"Autor: {livro.obter_autor()}")

    if isinstance(livro, LivroDigital):
        print(f"Tamanho: {livro.tamanho_em_mb} MB")
    elif isinstance(livro, LivroFisico):
        print(f"Numero de Páginas: {livro.numero_de_paginas}")

# Exemplo de Uso

mostrar_info_livro(ebook)        # Mostra informações detalhadas sobre o livro digital
mostrar_info_livro(livro_papel)  # Mostra informações detalhadas sobre o livro físico

Resumo

Neste capítulo, explorámos três conceitos fundamentais da Programação Orientada a Objetos:

  • Encapsulamento: Proteção de dados internos da classe e exposição de métodos públicos para acesso e modificação.
  • Herança: Criação de novas classes que herdam atributos e métodos de uma classe base.
  • Polimorfismo: Capacidade de tratar objetos de diferentes classes de uma forma unificada.

Quiz

  1. Qual é o objetivo principal do encapsulamento na POO?

    • a) Melhorar a sintaxe do código
    • b) Esconder os detalhes internos de uma classe
    • c) Tornar o código mais lento
  2. Como se indica um atributo privado em Python?

    • a) Usando uma única underscore (_)
    • b) Usando uma dupla underscore (__)
  3. O que é super() na herança?

    • a) Um método para criar novos objetos
    • b) Uma função que chama o construtor da classe base
    • c) Um nome de variável reservado
  4. Qual dos seguintes NÃO se refere a polimorfismo?

    • a) Diferentes classes podem ser tratadas como se fossem da mesma classe.
    • b) Polimorfismo garante que um método específico é chamado com base no tipo do objeto.
    • c) Polimorfismo força todas as classes a terem os mesmos métodos.
  5. Quais são os métodos usados para aceder aos atributos privados de uma classe?

    • a) Métodos de instância
    • b) Getters e Setters
    • c) Métodos estáticos
<< Atributos e Métodos Índice # Projeto 1: Sistema de B... >>