Рубрики
Без рубрики

Orientação objetos de Outra Forma: Herança

Algo que ajuda no desenvolvimento é reutilização de código. EM Orientação Objetos, Essa Reutiliza … Помечено ООП, Питон, Бразильидавс.

Algo que ajuda no desenvolvimento é reutilização de código. EM Orientação A objetos, Essa Reutilização Пока ocorer Através de Herança, Onde UM OBJETO Поде SE Comportar Como UM Objeto Da Sua Própria Classe, Como Também Da Classe Que Herdou.

Adicionando Funcoliadades.

UMA DAS Utilidades Da Herança é sttender UMA Classe Para Adicionar Funcallidades. Pensando No Contexto Das Postagens Andioneres, Poderíamos Querer Crar um Usuário E Senha Para Algumas Pessoas Pesserem Acessar o Sistema. Isso Poderia Ser Feito Adicionando Atributos Usuário E Senha Para As Pessoas, Além de Uma Função Para Валидар SE OS Dados Estão Corretos, E Assim Permitir o Acesso Ao Sistema. Porém Isso NãO PORE SER FEITO PARA TODAS AS PESSOAS, E SIM APENAS PARA AQUELES QUE TOUSUEM PERMISSãO de Acesso.

SEM Orientação abjetos

Voltando Solução Com Dicionários (SEM Utilizar Orientação A objetos), ISSO Custiria EM CRAIR EMMA DICIONARIO COM A ETRUTURA DE UMA PESSOA, E EM SEGUIDA ESTENDER ESSA ESTRUTURA COM OS NOVOS CAMPOS DE USUARIOI E SENHA NESMO MESMO DICIONIO, ALGO COMO:

# Arquivo: pessoa.py

def init(pessoa, nome, sobrenome, idade):
    pessoa['nome'] = nome
    pessoa['sobrenome'] = sobrenome
    pessoa['idade'] = idade


def nome_completo(pessoa):
    return f"{pessoa['nome']} {pessoa['sobrenome']}"
# Arquivo: pessoa_autenticavel.py

def init(pessoa, usuario, senha):
    pessoa['usuario'] = usuario
    pessoa['senha'] = senha


def autenticar(pessoa, usuario, senha):
    return pessoa['usuario'] == usuario and pessoa['senha'] == senha
import pessoa
import pessoa_autenticavel

p = {}
pessoa.init(p, 'João', 'da Silva', 20)
pessoa_autenticavel.init(p, 'joao', 'secreta')

print(pessoa.nome_completo(p))
print(pessoa_autenticavel.autenticar(p, 'joao', 'secreta'))

Porém Nessa Solução és usíval que o Программа esqueça de Chamar Как duas funções init DifeRentes, e como queremos que todo dicionário com entrutura de Pessoa_autenticavel Contenha Também a Estrutura de пессо , Podemos Chamar O init DE PESSOA DENTRO DO init департамент Pessoa_autenticavel :

# Arquivo: pessoa_autenticavel.py

import pessoa


def init(p, nome, sobrenome, idade, usuario, senha):
    pessoa.init(p, nome, sobrenome, idade)
    p['usuario'] = usuario
    p['senha'] = senha


...  # Demais funções
import pessoa
import pessoa_autenticavel

p = {}
pessoa_autenticavel.init(p, 'João', 'da Silva', 20, 'joao', 'secreta')

print(pessoa.nome_completo(p))
print(pessoa_autenticavel.autenticar(p, 'joao', 'secreta'))

Nesse Caso Foi BeanaRio ALTERAR O NOME DO ARDURATO пессо Д.А. Фунциано Pessoa_autenticavel.init PARA NãO FOFLITAR COM O OUTRO Módulo Importada Com Esse Mesmo Nome. Porém Ao Chamar UM init Doctro de Outro, Temos Garantia de que o Dicionário Será Compatível Tanto Com A Estrutura Pare Para Ser Criada Pelo Programador, Quanto Pelas Estruturas Pais Dela.

Com orientação objetos

class Pessoa:
    def __init__(self, nome, sobrenome, idade):
        self.nome = nome
        self.sobrenome = sobrenome
        self.idade = idade

    def nome_completo(self):
        return f'{self.nome} {self.sobrenome}'


class PessoaAutenticavel(Pessoa):
    def __init__(self, nome, sobrenome, idade, usuario, senha):
        Pessoa.__init__(self, nome, sobrenome, idade)
        self.usuario = usuario
        self.senha = senha

    def autenticar(self, usuario, senha):
        return self.usuario == usuario and self.senha == senha


p = PessoaAutenticavel('João', 'da Silva', 20, 'joao', 'secreta')

print(Pessoa.nome_completo(p))
print(PessoaAutenticavel.autenticar(p, 'joao', 'secreta'))

Основной новидадный Desse Exemplo é Que Ao Delaur Classe Pessoaautenticavel (Filha), FOI DEASEADO КЛУС Pessoa (PAI) Entre Parênteses, Isso FAZ O Интерпретатор Python Classe Classe Classe Estendendo a Com Ase estendendo a Com As Novas Funções que estamos Criando. Porém Poore Ser UM POUCO REDUNDANTE CHAMAR Pessoa .__ init__ Doctro da Função __init__ sendo que já foi deakenaado que ela stestende Pessoa , Подкадо Сер-Трокадо Пор Super () que aponta para classe que foi estendida. Exemplo:

class PessoaAutenticavel(Pessoa):
    def __init__(self, nome, sobrenome, idade, usuario, senha):
        super().__init__(nome, sobrenome, idade)
        self.usuario = usuario
        self.senha = senha

    ...  # Demais funções

Assim Se Evita Repetir o Nome Da Classe, e Já Passa Accessagement A Relementcia Para Я , Assim Como Quanto Usamos o Açúcar Sintático adresentado namyira postagem dessa série. E Esse Açúcar Sintática Também Poore Ser Usado Para Chamar Tanto Как Funções Takeradas EM Pessoa Quanto Em. Pessoa Autentica Vale Отказ Exemplo:

p = PessoaAutenticavel('João', 'da Silva', 20, 'joao', 'secreta')

print(p.nome_completo())
print(p.autenticar('joao', 'secreta'))

Esse Método Também Facilita A Utilização Das Funções, UMA VEZ QUE NãAO EMARIO LEMBRAR EM QUAL CLASSE QUE CADA FUNCHãO FOI DEALADA. Na verdade, como Pessoa Autentica Vale. stestene Pessoa Сериал Возвызов Executar Também Pessoaaautenticavel.nome_completo Porém Eles Apontam Para Mesma Função.

Собресскревендо Ума Фунчан

Клаз Pessoa Пожалуйста, Função nome_completo Que Retorna UMA ул ...| Содержание Nome E Sobrenome. Porém Нет Japão, Assim Como Em AutoS Países Asiáticos, O Sobrerome Vem Primeiro, E Até Estão Predindo Para Seguir Tradição Deles Ao Falarem Os NoMes de japoneses Como O Caso DO PAMEIRO-MINISRO, MUTANDO DE SHINZO ABE PARA ABE SHINZO.

Com orientação objetos

ISSO Também Pode Ser Feito No Sistema Usando Herança, Porém Em Vez de Criar UMA Nova Função Com Outro Nome, Essival Crar Umma Função Com O Mesmo Nome, Sobrescrevendo Ansior, Porém Apenas para os objetos da classe filha. ALGO SEMELHANTE AO QUE JA FOI FEITO COM AGRACHãO __init__ Отказ Exemplo:

class Japones(Pessoa):
    def nome_completo(self):
        return f'{self.sobrenome} {self.nome}'


p1 = Pessoa('João', 'da Silva', 20)
p2 = Japones('Shinzo', 'Abe', 66)

print(p1.nome_completo())  # João da Silva
print(p2.nome_completo())  # Abe Shinzo

Essa Relação de Herança Traz Algo Interestante, Todo Objeto Da Classe Япон SE Comporta Como UM Objeto Da Classe Пессо Porém a Relação Interna Não É Verdade. Assim Como PodeMos Dizer Que Todo japonês é Uma Pessoa, Mas Nem Todas как Pessoas São Japonesass. Ser Japonês ém ums Caso Mais Essicífico de Pessoa, Assim Como как Demais Nacionalidades.

SEM Orientação abjetos

Esse Comportamento de Sobrecrever A a Função nome_completo NãA É TãO Smples de Repplear Em Uma Estrutura de Dicionário, Porém É Asshival Fazer. Porém Como UMA Pessoa Pode Ser Tanto Japonês Quanto Não Ser, Não Essível Saber de Antemão Para Escrever No Código Pessoa.nome_completo ou japones.nome_completo , Que Diferente Do Exemplo Da Autenticação, Agora São Duas Funções Diferentes, Isso Precisa Ser Descoberto Dinamicamente Quando Se Precisar Chamar An Função.

UMA Forma de Fazer Isso E Gravelar UMA RELECLENCIA PARA A T Função Que Deve Ser Chamada Dentro Da Própria Estrutura. Exemplo:

# Arquivo: pessoa.py

def init(pessoa, nome, sobrenome, idade):
    pessoa['nome'] = nome
    pessoa['sobrenome'] = sobrenome
    pessoa['idade'] = idade
    pessoa['nome_completo'] = nome_completo


def nome_completo(pessoa):
    return f"{pessoa['nome']} {pessoa['sobrenome']}"
# Arquivo: japones.py

import pessoa


def init(japones, nome, sobrenome, idade):
    pessoa(japones, nome, sobrenome, idade)
    japones['nome_completo'] = nome_completo


def nome_completo(japones):
    return f"{pessoa['sobrenome']} {pessoa['nome']}"
import pessoa
import japones

p1 = {}
pessoa.init(p1, 'João', 'da Silva', 20)
p2 = {}
japones.init(p2, 'Shinzo', 'Abe', 66)

print(p1['nome_completo'](p1))  # João da Silva
print(p2['nome_completo'](p2))  # Abe Shinzo

Perceba que a forma demar a função foi elalada. O que acontece na prática é que toda função que pode ser sobrescriita não é chamada diretamente, e sim partir de uma refercia, e iso gera um custo custo computacional. COMO ESSE CUSTO NãO E TãO ALTO (MUITAS VEZES SENDO QUASE IRRELEVANTE), ESSE É O Comportamento Adotado EM Várias Lingugens, Porém EM C ++, POR Exemplo, existe Palavra-Shave виртуальный PARA DESCREVER QUANDO UMA FUNCHãO PORE CODE SER SOBRESCRITA OU NãO.

Рассматривать

Herança ém um mecanismo interestente para ser expressado com o objetivo de reaiproveiatar código e evitar repeti-lo. Porém Isso Code Vir Com Alguns Custos, Seja Computacional Durante Sua Execução, Seja Durante a Leitura do Código, Sendo NeautaRio Verivera DudaS Classes Para Saber o Que de Fato Está Sendo Executado, Porém Isso Também Pode Ser Usado Para Ocultar E abstrair Lógicas Mais Combicadas, Como Eu Já Comentei Em Outra Postagem.

Herança Também Premite Trabalhar Com Generalização E Esceialização, Podendo Descrever O Comportamentame Mais Geral, OU MAIS Essucialfico. Ou simplemente só adicionar mais funcionialidades Classe UMA já touchenteente.

Assim Como Foi Utilizado o Super () Para Chamar a Função __init__ DA CLASSE PAI, ESSILEL UTILIZA-LO PARA CHAMAR Qualkquer Outra Função. Isso Premite, POR Exemplo, Trastar OS Argageos Da Função, Appleando Modificações Antes de Chamar An оригинал Função Original, OU SEU RETORONO, Executando Algum Plachento Em Cima Do Retorno Dela, NãO Precisando Rescrever Toda A A Tunção.

Оригинал: “https://dev.to/acaverna/orientacao-a-objetos-de-outra-forma-heranca-3dm7”