Olá Debora! Tudo certo? Espero que sim. 🙂
Primeiramente, peço desculpas pelo atraso no retorno.
O ideal seria fazer atributos específicos para cada Classe e não repetir atributos em classes diferentes. Saber em qual classe colocamos determinado atributo é algo que, de fato, requer um pouco de prática e experiência. Porem, uma dica para ajudar a discernir melhor essa questão é se fazer algumas dessas perguntas:
- Esse atributo se refere a uma característica dessa classe?
- Esse atributo se sustenta apenas com a existência dessa classe?
- Para que esse atributo seja compreendido é necessário a existência de outra classe?
- Faz sentido essa classe existir sem esse atributo?
Sendo assim, no caso específico do exemplo dado por você (atributo tipo com valores PF e PJ), o atributo se encaixaria melhor em uma classe Cliente.
A justificativa para isso é que, dependendo do tipo de cliente (PF ou PJ), a própia conta pode ser diferente e pode haver a necessidade da existência de duas classes ContaPF e ContaPJ. Outro ponto interessante é que a existência de uma classe Cliente sem a presença do atributo tipo é mais inconcebível do que a classe Conta. Dessa forma, chega-se à conclusão que o atributo tipo é uma característica específica de Cliente.
Na linguagem Python é possivel que um dos atributos seja um objeto. Ou seja, é possível chamar um objeto dentro de um objeto.
Observe os seguintes códigos:
Classe Conta
class Conta:
def __init__(self, numero, titular, saldo, limite):
print("Construindo objeto ... {}".format(self))
self.__numero = numero
self.__titular = titular
self.__saldo = saldo
self.__limite = limite
def extrato(self):
print("Saldo de {} do titular {}".format(self.__saldo, self.__titular))
def deposita(self, valor):
self.__saldo += valor
def __pode_sacar(self, valor_a_sacar):
valor_disponivel_a_sacar = self.__saldo + self.__limite
return valor_a_sacar <= valor_disponivel_a_sacar
def saca(self, valor):
if(self.__pode_sacar(valor)):
self.__saldo -= valor
else:
print("O valor {} passou o limite".format(valor))
def transfere(self, valor, destino):
self.saca(valor)
destino.deposita(valor)
@property
def saldo(self):
return self.__saldo
@property
def titular(self):
return self.__titular
@property
def limite(self):
return self.__limite
@limite.setter
def limite(self, limite):
self.__limite = limite
@staticmethod
def codigo_banco():
return "001"
@staticmethod
def codigos_bancos():
return {'BB':'001', 'Caixa':'104', 'Bradesco':'237'}
Classe Cliente
class Cliente:
def __init__(self, nome, tipo, email):
print("Construindo objeto ... {}".format(self))
self.__nome = nome
self.__tipo = tipo
self.__email = email
@property
def nome(self):
return self.__nome
@property
def tipo(self):
return self.__tipo
@property
def email(self):
return self.__email
@nome.setter
def nome(self, nome):
self.__nome = nome
@tipo.setter
def tipo(self, tipo):
self.__tipo = tipo
@email.setter
def email(self, email):
self.__email = email
Podemos executar o seguinte comando para criar alguns objetos:
cliente1 = Cliente("Bruno", "PF", "bruno@alura.com")
conta1 = Conta(11111, cliente1, 500, 2000)
Perceba que coloquei como atributo de titular a variável que contém o objeto da classe Cliente. Para chamar informações de cliente a partir de conta, podemos executar o seguinte comando:
conta1.titular.nome
Isso resultará em 'Bruno'
.
Espero ter ajudado! Quaisquer dúvidas, estou à disposição. 😉
Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.Bons Estudos!