Em Python, usamos convenções como prefixar o nome dos atributos com um underscore (_
) para indicar que eles são privados. No entanto, esta é apenas uma convenção. Para garantir o encapsulamento, utilizamos métodos conhecidos como getters e setters.
Exemplo Básico
Vamos considerar uma classe chamada ContaBancaria
:
class ContaBancaria:
def __init__(self, titular, saldo=0):
self._titular = titular
self._saldo = saldo
def depositar(self, valor):
if valor > 0:
self._saldo += valor
print(f"Depósito de {valor}€ realizado com sucesso. Novo saldo: {self._saldo}€")
else:
print("Valor do depósito deve ser positivo.")
def levantar(self, valor):
if valor > 0 and valor <= self._saldo:
self._saldo -= valor
print(fLevantamento de {valor}€ realizado com sucesso. Saldo restante: {self._saldo}€")
else:
print("Valor inválido para levantamento.")
def obter_saldo(self):
return self._saldo
def definir_titular(self, novo_titular):
self._titular = novo_titular
def obter_titular(self):
return self._titular
Neste exemplo, os atributos _titular
e _saldo
são privados. Os métodos depositar
, levantar
, obter_saldo
, definir_titular
e obter_titular
são métodos públicos que permitem manipular e aceder aos dados de maneira controlada.
Utilização da Classe
conta = ContaBancaria("João")
conta.depositar(100)
conta.levantar(30)
print(f"Titular: {conta.obter_titular()}")
print(f"Saldo: {conta.obter_saldo()}")
Modificadores de Acesso em Python
Embora Python não tenha palavras reservadas para modificadores de acesso como private
e protected
em outras linguagens, segue-se uma convenção de nomenclatura. Abaixo, uma lista com as convenções mais comuns:
-
Atributos Públicos: Podem ser acedidos fora da classe.
self.atributo_publico = valor
-
Atributos Protegidos: Devem ser acedidos apenas dentro da classe e nas suas sub-classes.
self._atributo_protegido = valor
-
Atributos Privados: Não devem ser acedidos fora da classe. Em Python, isto é implementado usando dois underscores
__
no início do nome do atributo.self.__atributo_privado = valor
Implementação de Getters e Setters
Para criar métodos getters e setters de forma mais eficiente em Python, podemos utilizar a função property
. Veja o exemplo:
class ContaBancaria:
def __init__(self, titular, saldo=0):
self.__titular = titular
self.__saldo = saldo
@property
def saldo(self):
return self.__saldo
@saldo.setter
def saldo(self, valor):
if valor >= 0:
self.__saldo = valor
else:
print("Saldo não pode ser negativo.")
@property
def titular(self):
return self.__titular
@titular.setter
def titular(self, novo_titular):
self.__titular = novo_titular
Resumo
Neste capítulo, explorámos o conceito de encapsulamento, uma prática essencial da POO que ajuda a proteger os dados internos de uma classe e melhora a manutenção de código. Vimos como implementar encapsulamento em Python usando convenções de nomenclatura e métodos getters e setters. Com o uso adequado do encapsulamento, conseguimos criar programas mais seguros, modulares e fáceis de manter.
Quiz
-
Qual é o objectivo principal do encapsulamento?
- a) Facilitar a ligação entre componentes.
- b) Proteger os dados internos de uma classe.
- c) Aumentar o desempenho do programa.
- d) Reduzir o tamanho do código.
-
Em Python, como se indica que um atributo é privado de uma classe?
- a) Prefixando com um underscore (
_
). - b) Sufixando com um underscore (
_
). - c) Prefixando com dois underscores (
__
). - d) Utilizando a palavra
private
.
- a) Prefixando com um underscore (
-
O que acontece se tentar aceder diretamente a um atributo privado fora da sua classe?
- a) É permitido sem erros.
- b) A operação é bloqueada e um erro é lançado.
- c) O valor retorna, mas o código dá um aviso.
- d) O programa continua, mas o valor do atributo não é retornado.
-
Qual das seguintes opções é a melhor prática para alterar um valor de atributo privado em Python?
- a) Alterar diretamente sem métodos intermediários.
- b) Utilizar um método
__init__
. - c) Utilizar métodos getters e setters ou
property
. - d) Alocar o atributo em uma lista.
Respostas
- b) Proteger os dados internos de uma classe.
- c) Prefixando com dois underscores (
__
). - b) A operação é bloqueada e um erro é lançado.
- c) Utilizar métodos getters e setters ou
property
.