1
resposta

Diferença entre usar super() e usar a classe mãe como argumentos nas subclasses.

Olá,

Apenas para que os conceitos da aula fiquem mais claros em minha cabeça e eu consiga compreender de fato o que está acontecendo:

1 - Ao usar, como no exercício, "Programa" como argumento das subclasses, todos os métodos da classe mãe (Programa) se tornam disponíveis às subclasses com esse argumento?

2 - Utilizar:

super().__init__(nome, ano)

apenas é útil para que os argumentos sejam reaproveitados?

3 - Se por meio da função super é possível acessar qualquer método da classe mãe, qual a diferença de fato entre usar a classe Programa como argumento ou simplesmente utilizar super?

1 resposta

Então, sua pergunta não ficou tão clara para mim, então vou explicar como eu entendi a sua pergunta.

Você quer saber porque usar

super().__init__(nome, ano)

no lugar de

Programa.__init__(nome, ano)

Vou então compartilhar aqui o que eu descobri, o que eu entendi e o que eu deduzo testando ambos num arquivo que abri aqui. Esse foi meu código de teste:

from modelo import Programa

class Teste(Programa):

    def __init__(self, nome, ano):
        super().__init__(nome, ano)

    def quantos_super(self):
        print(f"Temos: {super().likes} likes")

    def quantos_Programa(self):
        print(f"Temos: {Programa.likes} likes")



testando = Teste("Qualquer", 2000)
testando.quantos_super()
testando.quantos_Programa()

Descobri que: se você colocar Programa.__init__(nome, ano) não vai rodar e o compilador vai reclamar que falta o "ano", (ele entendeu que o nome = self da classe programa e o ano = nome do programa) se você passar o self antes ele roda normalmente.

Até ai tudo certo não parece ter muita diferença entre os dois, mas quando eu fui tentar na função pra imprimir os likes aconteceu o seguinte:

testando.quantos_super()
>> Temos: 0 likes
testando.quantos_Programa()
>> Temos: <property object at 0x103fa2b30> likes

Se você usar o Programa.likes ele vai retornar onde fica a propriedade likes na classe Programa.

Pesquisando um pouco vi falarem que o que a classe super faz é criar temporariamente um objeto dos objetos pai/mãe e assim acessar e executar algum método que você chamar.

Sabendo isso mudei algumas coisinhas pra testar outra vez.

    def quantos_Programa(self,):
        print(f"Temos: {Programa(self.nome,self.ano).likes} likes")

isso parece funcionar porém olhe o resultado se você tentar dar likes:

testando = Teste("Qualquer", 2000)
testando.dar_like()
testando.quantos_super()
>> Temos: 1 likes
testando.quantos_Programa()
>> Temos: 0 likes

Então por mais que se eu criar um objeto Programa dentro da funçãoquantos_Programa ele não vai retornar as alterações feitas a classe Teste que alterem os likes por exemplo.

Tambem aproveitei pra testar o super() com multiplas heranças:

+ class Testando:
+    pass
 +   print("testou")

- class Teste(Programa):
+ class Teste(Programa,Testando):

    def __init__(self, nome, ano):
        super().__init__(nome, ano)

    def quantos_super(self):
        print(f"Temos: {super().likes} likes")

    def quantos_Programa(self):
        print(f"Temos: {Programa(self.nome,self.ano).likes} likes")

    def qual_ano(self):
        print(f"{self.nome} foi feito no ano {self.ano}")



testando = Teste("Qualquer", 2000)
testando.dar_like()
testando.quantos_super()
testando.quantos_Programa()

Agora quando você executa o código o "testou" vai aparecer antes do Temos: X likes(no caso 1 like). Isso acontece pois ao chamar o super dentro do __init__* você acaba iniciando todos as heranças da classe.

*Dedução minha que é somente chamando o super dentro do __init__ que isso acontece visto que nas outras chamadas isso não aconteceu

Minha conclusão é que para evitar bugs e ter mais funcionalidades mais facilmente é melhor usar o super().