Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Dúvida no Tópico - Orientação a objetos - Heranças

Prezados,

Gostaria de saber a razão da classe "filha" ter acesso a todos os atributos da classe "Mãe" com excessão de um deles(__curtidas). Segue abaixo o código e os testes realizados:

Código

-- coding: utf-8 --

class Perfil(object): 'Classse para moldar perfis de usuarios'

def init(self, nome, telefone, empresa): self.nome = nome self.telefone = telefone self.empresa = empresa self.__curtidas = 0

def obter_curtidas(self): return self.__curtidas

def curtir(self): self.__curtidas+=1

def imprimir(self): print 'Nome %s, Telefone %s, Empresa %s, Curtidas: %s' % (self.nome, self.telefone, self.empresa, self.__curtidas)

class Perfil_Vip(Perfil): 'Classse para moldar perfis de usuarios Vips'

def obter_creditos(self): return self.__curtidas ** 10

Testes

from models import * vip = Perfil_Vip('Rafael', 'N/A', 'Empresa X') vip.nome 'Rafael' vip.telefone 'N/A' vip.empresa 'Empresa X' vip.curtir() vip.imprimir() Nome Rafael, Telefone N/A, Empresa Empresa X, Curtidas: 1

Agora... Quando tento utilizar a função obter_creditos(): da classe Vip tomo o erro abaixo:

vip.obter_creditos() Traceback (most recent call last): File "", line 1, in File "models.py", line 26, in obter_creditos return self.curtidas ** 10 AttributeError: '_Perfil__curtidas', object has no attribute '_Perfil_Vip__curtidas'

Informações sobre o objeto:

vip.dict {'empresa': 'Empresa Z', '_Perfil__curtidas': 1, 'telefone': 'na', 'nome': 'Grasi'}

dir(vip) ['_Perfil__curtidas', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduceex\_', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'curtir', 'empresa', 'imprimir', 'nome', 'obter_creditos', 'obter_curtidas', 'telefone']

OBS: Podemos perceber que o atributo _curtidas encontra-se com a referência _Perfil__curtidas(classe mãe) ao invés de _Perfil_Vip__curtidas(classe filha)

6 respostas

Você precisa usar o método obter_curtidas, caso contrário, não será possível acessar o atributo __curtidas da classe pai, devido ao prefixo __ que muda o nome da variável escondendo-a.

Veja que em sei código você acessa o atributo direto.

Bom dia Professor,

A aula mostra como resolver essa questão, mas não a razão desse problema. O que não entendi é porque a classe filha herda todos os atributos, menos esse. Por que razão a herança não funciona para atributos com prefixo curtidas? Eu entendi que o nome do atributo é alterado para acesso externo, mas internamente(dentro da própria classe) é possível acessá-lo com curtidas. Não deveria ser assim também na classe que herda dessa? Poderia me explicar a razão disto? Procurei na documentação mas não encontrei nada.

Obrigado.

solução!

Isso é o princípio do encapsulamento. Se a classe filha puder alterar o estado da classe pai, ela está ferindo o encapsulamento. Veja que a única maneira de incrementar __curtidas é através de curtir e para lê-lo o método obter_curtidas. Lá esta garantida a regra de que você só pode incrementar de 1 em 1. Se vc herdasse e a classe filha pudesse alterar diretamente o __curtidas ela passaria por cima da regra definida no pai. É por isso que a filha tem que pedir a um método do pai.

Em linguagens como Java, há modificadores de acesso, há o protected que permite que a classe filha acesse o atributo da classe pai. Isso não existe em Python.

Você não encontrou na documentação porque isso tem mais relação com princípios de OO do que o Python em sim.

Espero ter esclarecido sua dúvida. Aguardo seu retorno.

Ficou mais claro agora. Muito obrigado!

Rafael, excelente! Agora é continuar estudando. Python é uma linguagem interessante, multiparadigma (OO, Funcional, procedural). Nesse treinamento eu quis dar uma ênfase na orientação a objetos.