Transcrições
1. Introdução: Quem me dera ter conhecido este segredo há muito tempo. Eu vou te dizer agora, há duas maneiras de crescer como um codificador. Primeiro, você pode levar anos para praticar
100 erros por cada princípio de codificação que você adotar. Dois, você pode levar dias, até horas aprendendo esses mesmos princípios com outro codificador. Aqui está o kicker. Uma das coisas mais importantes que um programador sênior pode ensinar é maneiras de pensar sobre código. Uma dessas maneiras é Programação Orientada a Objetos, ou OOP, para encurtar, o molho secreto para levar seu código para o próximo nível. Olá, sou o Alvin. Na UC Berkeley, ensinei mais de 5.000 alunos. De aulas de matemática discreta ao aprendizado de máquina. Estarei passando a vocês a sabedoria que professores, engenheiros sênior e mentores me deram para que possam crescer mais rápido como programador do que eu jamais fiz. Nesta aula, você aprenderá a pensar criticamente como programador. Esse pensamento crítico permitirá que você modele o mundo ao seu redor como uma série de objetos diferentes interagindo uns com os outros. Esse pensamento crítico também permitirá que você classifique códigos legíveis, sustentáveis e flexíveis. OOP é usado em todos os lugares, para jogos, para aprendizado de máquina, para ciência de dados. No final deste curso, você entenderá por que e como. Você será capaz de imitar em código uma loja de bicicletas processando reparos, um caminhão de sorvete gerenciando ordens, ou um controlador de tráfego aéreo dirigindo aviões. Esta classe Coding 101 plus é escrita para iniciantes que estão interessados em um, nivelando seu código ou dois, frustrado tentando aprender Programação Orientada a Objetos. Se for você, não se preocupe. Já tive minha cota de confusão
no passado e espero ajudá-lo com sua confusão agora. Note que esta classe não espera alguma familiaridade de codificação com Python. Se você ainda não está familiarizado, certifique-se de fazer o meu curso de Coding 101: Python for Beginners para ser apanhado. Suas conquistas desta classe não serão uma sintaxe estranha ou regras específicas do Python. Em vez disso, é uma forma de pensar. Você só precisa da intuição para aplicar esses conceitos, mesmo se você esquecer o que os conceitos são chamados. Além desses conceitos, espero ajudá-lo a construir confiança;
leitura de confiança , escrita, falar sobre conceitos de OOP. Agora, vamos começar a construir com Programação Orientada a Objetos.
2. Projeto: Nesta classe, seu projeto é construir uma simulação usando os conceitos que você aprendeu. Como exemplos, você estará construindo um caminhão de sorvete gerenciando pedidos e um modelo mínimo de interruptores de luz em uma casa. Sua simulação pode ser para qualquer coisa. Uma loja de bicicletas processando reparos, um armazém processando remessas a granel, ou um controlador de tráfego aéreo gerenciando aeronaves. Escolha o cenário que quiser. Apenas certifique-se de que seu cenário tem muitos tipos diferentes de objetos interagindo. A simulação que você constrói é poderosa. No futuro, você pode adicionar uma interface para torná-lo um aplicativo de gerenciamento, usar este sistema para prever o futuro de um sistema muito complexo ou construir um jogo com ele. Nesta classe, não vamos cobrir os sinos e assobios, por exemplo, como adicionar uma interface. Em vez disso, vamos nos concentrar no núcleo, uma série de objetos interagindo e como tornar esse código flexível, escalável e sustentável. Esta é uma ótima maneira de entender o poder da programação
orientada a objetos e como usá-lo de forma eficaz. Como você deve ter ouvido de uma das minhas aulas anteriores, meu lema é dar a você a emoção de aprender mais, não necessariamente entregar-lhe uma lista de roupas diferentes utilitários Python. O mesmo se aplica nesta classe. Mas aqui eu também quero dar-lhe a intuição de escrever um código melhor e mais limpo. Para fazer isso, vamos codificar cada conceito,
não uma, mas duas vezes. Faremos isso especificamente em quatro fases diferentes. Primeiro, abordaremos o paradigma OOP, a filosofia e a base da programação orientada a objetos. Segundo, herança, maneiras de tornar o OOP menos redundante, melhorando a inteligibilidade. Finalmente, mixins e composição, maneiras de tornar OOP facilmente extensível e flexível. À medida que praticamos cada um desses conceitos, quero que você sinta o que está errado e o que é certo na criação de código. Esquecer esses termos e definições exatos não fará muita diferença, o que você quer é a intuição de escrever um código mais limpo e melhor. Cada uma das quatro fases é dividida em três partes diferentes. A primeira parte é o conceito, introduzindo as ideias, termos e definições. A segunda é a prática. Em seguida, você usará esses conceitos em dois exemplos diferentes. Algumas fases serão acompanhadas por uma lição misteriosa. Esta lição misteriosa aborda um conceito especial de OOP. Estes mistérios são bugs reais que os alunos já encontraram antes. Espero que essas lições possam poupar alguma dor e confusão no futuro. Você pode ter ouvido falar de outros conceitos de OOP como polimorfismo ou encapsulamento. Mencionei esses termos brevemente, mas não em detalhes, pois acredito que o núcleo do OOP reside nos termos que abordaremos, abstração, herança, mixins e composição. Há um grande número de lições, mas eu projetei cada lição para ser relativamente curto e mordida tamanho para que você possa esperar tomar cada uma dessas lições em movimento, em seu trajeto, em pausa no banheiro, a qualquer momento realmente. Espero que esteja animado para começar a construir sua simulação. Vamos começar.
3. Conceito: paradigma OOP: Nesta lição, vou apresentar o paradigma de programação orientada a objetos. Não haverá nenhum código nesta lição. O objetivo é simplesmente introduzir a maneira OOP de pensar. Abordaremos três conceitos nesta lição. O primeiro conceito é a diferença entre uma classe e uma instância. Aqui temos um sorvete modelo. Mais tarde, falaremos sobre o que esse modelo realmente contém. Por enquanto, pense neste modelo como sua expectativa de um sorvete. Você espera ser capaz de comê-lo, você espera uma colher de sorvete e um cone de sorvete, e talvez você espere sabor de baunilha por padrão. No entanto, este modelo, sua expectativa é imaginária. Aqui temos um sorvete de verdade que você pode comer. Observe que você pode gerar várias porções de um único modelo. Observe também que você pode comer cada porção a taxas diferentes. Uma porção pode ter uma colher esquerda e a outra pode não ter mais colheres. Agora vamos renomear modelo e servir. Em vez de modelo, vamos chamar isso de uma classe. A aula de sorvete é a sua expectativa de um sorvete, o que ele contém e como você pode interagir com ele. Dissecaremos isso com mais detalhes na próxima seção. Em vez de servir, vamos chamar essas instâncias. Uma instância de sorvete é um sorvete real que você pode comer. Como antes, observe que você pode gerar várias instâncias de uma única classe. Você também pode comer cada instância a uma taxa diferente. Uma instância pode ter uma colher esquerda e a outra pode não ter mais scoops. Na terminologia OOP, dizemos que definimos a classe de sorvete. Nesta lição, vou dar a vocês vários blocos de construção fundamentais para como projetar essas aulas. Vamos começar com a definição de métodos. Nesta seção, vamos falar sobre métodos de classe. Nós realmente usamos métodos em Coding 101 Python para iniciantes, mas nesta classe, estaremos definindo métodos. Para entender o método, vamos voltar ao nosso exemplo de sorvete. Os métodos nos ajudam a definir o que posso fazer com sorvete. Bem, podemos comer e adicionar bolas ao nosso sorvete, e é isso. Estas duas acções são os nossos métodos. Vamos codificar esses métodos mais tarde. Na terminologia OOP, projetamos nossa classe de sorvete para incluir os métodos de comer e adicionar colheres. Novamente, projetamos nossa classe de sorvete para incluir os métodos de comer e adicionar colheres. Isso conclui métodos. Mas agora, como implementamos esses métodos? Bem, cada um dos nossos sorvetes precisa saber quantas bolas sobraram. Isso nos leva a atributos. Atributos são pedaços de informação. Vamos primeiro nos concentrar em informações específicas para uma instância ou uma porção de sorvete. Voltando ao nosso exemplo de sorvete, que informações são específicas para cada instância de sorvete? Primeiro, o número de colheres restantes pode diferir entre as instâncias de sorvete. Em segundo lugar, o sabor do sorvete pode diferir entre instâncias de sorvete. Na terminologia OOP, projetamos nossa classe de sorvete para incluir os métodos de comer e adicionar colheres. Ele também inclui atributos para o número de colheres restantes e o sabor do sorvete, e é isso. Estes são os blocos de construção da programação orientada a objetos. Para recapitular, cobrimos a diferença entre classes ou modelos e instâncias. Também discutimos a regra dos métodos que descrevem como interagir com uma instância. Nós mencionamos atributos que contêm informações sobre uma instância. Sei que houve muitos termos nesta lição, mas não se preocupe, continuaremos a usar esses termos de novo e de novo nas próximas lições. No final desta aula, você estará cansado de ouvir as palavras classe, instância, método e atributo. Mas você também entenderá esses termos muito mais profundamente. Para obter uma cópia desses slides e mais recursos, confira o site do curso. Isso conclui nossa lição, o Paradigma de Programação Orientada a Objetos. Na próxima lição, começaremos a simular um caminhão de sorvete usando esses conceitos.
4. Prática: sorvete: Nesta lição, vamos escrever nosso primeiro pedaço de código usando programação orientada a objetos. Comece navegando para responder. it/languages/python3. Sugiro pausar o vídeo aqui e criar uma conta, caso ainda não o tenha feito. Enquanto você pode codificar sem uma conta, uma conta permite que você salve seu código. Então, sugiro colocar suas janelas Skillshare e Repl.it lado a lado, como mostrado aqui. Assim, você pode codificar junto comigo. O primeiro passo é definir sua primeira classe. Aqui está como. Qualquer caractere em preto é obrigatório. Deve ser digitado exatamente dessa maneira. Começamos com a palavra-chave classe em preto, em
seguida, adicionamos o nome da classe denotado em azul. Como muitos outros conceitos Python que você aprendeu, adicione dois pontos, depois adicione dois espaços e, por enquanto, use passe. Pass é apenas um espaço reservado para outro código que vamos escrever mais tarde. Vamos codificar isso agora. Nesta lição, vamos criar uma aula de sorvete. Vamos usar o formato que vemos à esquerda, digite na classe, Sorvete. Acertar cólon. Depois de digitar Enter, Repl.it criará automaticamente dois espaços para você. Agora, digite o passe. Vou bater em Escape para descartar este modal. Isso é tudo para a sua primeira aula. Vamos usar essa classe agora para criar uma instância. Chamamos esse processo de criação de uma instância a partir de uma instanciação de classe. Aqui está como instanciar. Instanciação é realmente apenas a metade direita deste formato, digite o nome da classe em azul, em
seguida, adicione dois parênteses, e isso é tudo que você precisa para instanciar. Também atribuiremos essa instância à direita a uma variável à esquerda. Assim como com a definição de qualquer outra variável, temos o nome da variável em rosa à esquerda, um sinal de igual preto com espaços opcionais e, em seguida, o valor. Nesse caso, o valor é a instância. Vamos codificar isso agora. Antes de começar, certifique-se de executar seu arquivo pressionando “Executar”, a seta verde na parte superior. Em seguida, usaremos o prompt interativo para testar nosso código. Seu prompt interativo pode estar no lado direito da tela. Mudei o layout para que o meu fique no fundo. Primeiro, digite o nome da variável
e, em seguida, instancie digitando o nome da classe e os parênteses. Vamos agora ver o que o sorvete variável contém e o contém nossa instância ou nosso objeto. O próximo conceito é um método. Agora adicionaremos uma ação ou comportamento à nossa classe. Isto é o que temos até agora. Para adicionar um método, nós simplesmente definir uma função dentro da classe. Isso deve parecer familiar, a palavra-chave def que já vimos antes. Usamos def para definir funções também. A única diferença é que nosso primeiro argumento para o método deve ser auto denotado em preto aqui. Aqui, temos o nome do método em azul, o conteúdo do método em laranja e espaços em cinza. Vamos codificar isso agora. Dentro do seu editor, vamos agora excluir este passe e adicionar o método eat, então def eat auto cólon, assim como vemos no lado esquerdo. Agora, vamos digitar impressos, e eu vou escrever Yum. Isso é tudo para definir o seu método de comer. Vamos agora testar ou usar esse método. Para testar ou usar este método, use as expressões de ponto recuperadas no curso Python para iniciantes, digite o nome da variável de instância, que é ice no nosso exemplo, adicione um ponto mostrado em preto e
adicione o nome do método em azul. Finalmente, use dois parênteses para realmente chamar o método assim como chamamos funções. Vamos codificar isso agora. Novamente, não se esqueça de executar o arquivo clicando na seta verde. Primeiro, instanciar, então sorvete equivale a Sorvete com parênteses. Em seguida, chame o método de comer. Vamos usar o modelo no lado esquerdo, sorvete, nossa variável name.eat. Aperte Enter e obtemos Yum, que é a nossa declaração de impressão no corpo do método de comer. Agora, introduzimos um conceito chamado construtor. O código no construtor é executado quando a classe é instanciada. Deixe-me mostrar-lhe pelo exemplo. Aqui está um exemplo de construtor. Observe que a primeira linha é toda preta. Você deve copiar exatamente isso por enquanto. Como sempre, você pode colocar o código que quiser em laranja no corpo do método. Aqui, nosso construtor simplesmente imprime alto. Vamos codificar isso agora. Vamos adicionar um construtor à nossa aula de sorvete. Aqui, teremos def_init_self cólon, assim como vemos no lado esquerdo, e então vamos imprimir algo memorável. Neste caso, vamos dizer impressão Criado sorvete. Vou adicionar uma linha de piscar aqui só para manter o nosso código limpo e legível. Mais uma vez, execute seu arquivo pressionando a seta verde. Agora vamos instanciar nossa aula de
sorvete, sorvete igual ao sorvete e aqui, você pode ver sorvete criado. Agora, para o nosso conceito final, um atributo. Atribuir um atributo é muito semelhante à definição de uma variável. Aqui, temos o nome do atributo em rosa e o valor em laranja. Observe, no entanto, que temos o ego. em preto. Isto é importante. É assim que anexamos o atributo à instância de gelo atual. Self sempre se referirá à instância atual. Vamos codificar isso agora. Exclua o conteúdo de um construtor. Em vez disso, vamos adicionar self.scoops igual a 3. Isso atribui o número de colheres a três. Vamos testar isto. Execute seu arquivo clicando na seta verde no topo. Então, instancie sua aula de sorvete. Verifique o número de colheres. Aqui, teremos a instância.scoops. Aqui, temos três como esperado. Essa não foi a última parte da lição. Na verdade, temos mais dois trechos de código para revisar. Vamos mudar o nosso método de comer para contabilizar o número de colheres comidas. Esta foi a nossa definição de método anterior com o nome do método em azul e o conteúdo do método em laranja. Agora, adicionamos um argumento em verde. Podemos então usar esse argumento de entrada verde, neste caso, y em nosso método. aqui usamos y para calcular y vezes y. Nós também temos o nome do método em azul, o conteúdo do método em laranja e espaços. Vamos codificar isso agora. Em nosso método eat, vamos adicionar um argumento de entrada chamado scoops. Isso permitirá que o usuário de sorvete coma quantas colheres quiser ao mesmo tempo. Agora, vamos atualizar o número de colheres que o sorvete deixou. Em vez de imprimir Yum, adicione self.scoops igual ao total original, mas menos o número de colheres que queremos comer. Eu também vou introduzir outra maneira de escrever esta linha de código que é muito mais curta. Nós também podemos substituir isso por self.scoops menos é igual a colheres. Essas duas linhas são exatamente as mesmas, então vou deletar a primeira aqui. Esta linha diz diminuir o número de colheres pelo número de colheres que queremos comer. Vamos rever como chamar um método. Da esquerda para a direita, temos o nome da variável de instância em rosa, um ponto, e o nome do método em azul, em seguida, o argumento de entrada em verde. Vamos tentar isso agora. Vá em frente e clique no botão verde na parte superior para executar seu arquivo. Em seguida, digite sorvete igual ao Sorvete. Isso instancia. Então, vamos verificar quantas bolas estão contidas atualmente, que são três. Então, vamos comer ou chamar o método de comer com o argumento dois como vemos no lado esquerdo. Isso vai comer duas colheres, e vamos verificar quantas bolas sobraram. Temos um furo como esperado. Isso conclui nossos fundamentos para escrever código de programação orientado a objetos. Para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Você pode estar pensando, “Santa vaca, há muitos novos termos. Isso é bastante avassalador.” Se for você, não se preocupe. Eu também estava lá em algum momento. Sinta-se livre para pular para a próxima lição, que é prática para continuar a desenvolver familiaridade com esses termos de OOP. Alternativamente, se você estiver interessado em alguns problemas desafiadores de prática de bônus, continue a lição. Agora, vamos ao nosso treino de secção de bónus. Vamos praticar o uso da terminologia nesta lição adicionando mais dois trechos de código. Primeiro, para revisar, este método eat leva em um argumento scoop e subtrai que muitas colheres do número total de colheres. Agora, para praticar, crie um método chamado add que leva em um argumento scoops e adiciona que muitos scoops ao total. Pause o vídeo aqui e tente isso agora. Se você não sabe por onde começar, tudo bem. Você vai conseguir isso com mais repetição. Vamos agora escrever o método, adicionar. Logo abaixo do nosso método cada, vamos definir add. Novamente, o primeiro argumento é sempre auto. Em seguida, adicione o argumento scoops. Devemos então adicionar esse número de colheres ao total. Isso conclui nosso método de adição. Vamos praticar outro. Isto irá testar o seu conhecimento a partir da classe 101 de codificação Python. Hora de revisar se as declarações se você as esqueceu. No método eat, verifique se o número de colheres restantes é menor que o número de colheres que o usuário está tentando comer. Se assim for, não imprima bytes suficientes; caso contrário, deduza o número de scoops do total, como de costume. Novamente, pause o vídeo aqui para tentar. Se você não sabe como fazer isso, não se preocupe. Com mais prática virá mais familiaridade. Agora, vamos aumentar o nosso método de comer. Vamos verificar se o número de colheres é menor que o número de colheres que o usuário está tentando comer. caso afirmativo, não imprime bytes suficientes. Caso contrário, deduzir um número de colheres no total como de costume. Isso conclui o nosso método de alimentação aumentada. Isso é tudo para esta lição. Novamente, na próxima lição, teremos alguma prática para continuar a construir familiaridade com esses termos OOP.
5. Prática (bônus): interruptor de luz: Bem-vindos ao treino de bónus. Nesta lição, vamos criar uma simulação para uma série de luzes. Assim como antes, navegue para responder. it/languages/python3. Então eu sugiro colocar suas janelas Skillshare e responder .it lado a lado, como mostrado aqui. Primeiro, é como você deve definir sua classe. Temos a palavra-chave classe em preto, nome
da classe em azul, dois pontos, dois espaços e o corpo da classe em laranja, que é o espaço reservado para passagem por enquanto. Vamos codificar isso. Nesta lição, vamos simular um interruptor de luz. Então vamos chamar a nossa turma de Luz. Class Light: “Enter”, que criará dois espaços para nós e vá em frente e digite “Pass”. Vamos agora criar uma instância de nossa classe ou instanciar nossa classe. No lado direito, temos o nome da classe em azul e parênteses em preto. É tudo o que precisamos para instanciar a turma. No entanto, devemos atribuir esta instância a uma variável. Temos o nome da variável em rosa, igual a sinal em preto com espaços opcionais e o nome da classe em azul. Vamos agora codificar isso. Vá em frente e aperte a seta verde no topo para executar seu código. Novamente, vamos agora digitar o nosso intérprete. Para você, seu intérprete pode estar no lado direito da tela, meu está na metade inferior. Vamos agora definir a variável que é leve, e o nome da classe com parênteses para instanciar. Vamos ver o que a variável de luz contém e ela contém uma instância ou um objeto. Vamos agora adicionar a capacidade de ligar e desligar a luz. Aqui está a classe em nosso exemplo, e aqui está o método add. Temos a palavra-chave def em preto, nome do
método em azul e o corpo do método em laranja, juntamente com os espaços em cinza. Agora vamos definir um método de alternância usando este formato. Substitua a palavra-chave pass e, em vez disso, digite def toggle novamente com o argumento self e imprima “Alternar ativar e desativar!”. Vou apertar “Escape” para descartar este modelo. Agora, devemos ver como testar este programa. Estas são as expressões de ponto que você já viu antes. Temos o nome da variável de instância em rosa, um ponto em preto, o nome do método em azul e os parênteses em preto novamente. Esses parênteses são necessários para codificar o método. Vamos agora testar este programa. Primeiro, execute o código clicando na seta verde no topo. Instanciar sua luz, em seguida, chamar o método de alternância, light.toggle e aqui temos nossa declaração de impressão. Nesta próxima seção, vamos cobrir o construtor. Aqui está um exemplo de construtor com a primeira linha completamente em preto e o corpo do construtor em laranja. Temos a expressão aqui e os espaços em cinza. Vamos agora adicionar um construtor. Vamos definir init com o argumento de auto e então vamos imprimir “Criando luz”. Como antes, vou adicionar um espaço para legibilidade. Novamente, execute seu código clicando na seta verde na parte superior e digite “Luz igual a Luz” para instanciar. Aqui, temos a declaração impressa que escrevemos antes. Agora vamos adicionar atributos para rastrear o estado interno da luz, seja ela ligada ou desligada. Este é o formato para definir atributos. Temos um auto-ponto em preto, o nome do atributo em rosa e o valor em laranja. Self sempre se refere à instância atual. Vamos codificar isso agora. Primeiro, no construtor, definimos On como False. Então, dentro do método de alternância, vamos verificar se a luz está acesa no momento. Então, se self.on: então definimos a luz para False e se ela não estiver ligada no momento, então a ligamos. Nós podemos realmente resumir rapidamente essas quatro linhas de código usando apenas uma linha de código digitando em self.on é igual a não self.on. Se o self.on for verdadeiro, não verdadeiro nos dará falso. Se o self.on for verdadeiro, não verdadeiro nos dará falso. Então não nos permite simplesmente alternar entre verdadeiro e falso. Novamente, esta linha é exatamente a mesma que estas quatro linhas. Vou apagar estas primeiras quatro linhas e este é o nosso método de alternância. Vamos agora testar o nosso código. Mais uma vez, aperte a seta verde para executar o seu código e vamos instanciar a nossa luz. Vamos verificar se está ligado ou não. No momento, não está ligado. Vamos alternar a luz e verificar se ela está ligada novamente e está realmente ligada. Nosso código funciona. Para obter uma cópia desses slides e o código concluído para esta lição, verifique o site do curso. Isso conclui nossa lição de prática. Espero que esteja familiarizado com a terminologia até agora. Não há necessidade de memorizar os formatos que cobrimos. Primeiro, você sempre pode procurar. Segundo, em virtude de ver repetidamente esses formatos de novo e
de novo, no final deste curso, você estará mais familiarizado com eles do que está agora. Na próxima lição, visitaremos um bug misterioso e como corrigi-lo. Se você quiser praticar com problemas mais desafiadores, continue assistindo a esta lição para uma prática. Como na última lição, agora
temos uma prática bônus. Crie um método chamado is_on que retorna se a luz está acesa ou não. Pause o vídeo e experimente isso agora, e aqui está a solução. Nós vamos adicionar outro método dentro da classe Light chamado is_on. Mais uma vez, você precisa de sua auto-argumentação, e nós vamos simplesmente retornar soft.on. Eu vou apertar “Escape” para descartar este modelo e ir em frente e executar o seu código clicando na seta verde. Vou instanciar a luz e aqui vamos verificar,
é a luz acesa digitando light.is_on. Certifique-se de codificar seu método com parênteses e, de fato, é falso. Agora, vamos alternar a luz para que ela esteja ligada e verificar, está ligada? Na verdade, isso é verdade. Nosso método funciona. Como dissemos antes, isso conclui nossa lição e na próxima lição, visitaremos um bug misterioso e como corrigi-lo.
6. Mistério (bônus): luzes sincronizadas: Nesta lição, abordaremos um bug misterioso e como corrigi-lo. Observe que esses mistérios abordam algumas das partes mais confusas do OOP. Se você está se sentindo sobrecarregado, sugiro pular essas seções misteriosas na primeira passagem, revisitando-as em uma segunda passagem para o curso. Assim como antes, navegue para responder. it/languages/python3. Então eu sugiro colocar suas janelas Skillshare e Repl.it lado a lado, como mostrado aqui. Primeiro, é a turma. Tente criar uma classe chamada Luz. Pausar o vídeo aqui se você não quiser uma dica. Aqui está a sua dica. Este é o formato para uma definição de classe. Vamos agora escrever a solução. Vamos definir uma classe Light. Para este próximo passo, vamos instanciar estas luzes. Instancie as classes Light duas vezes, nomeie suas instâncias a e b. Pause seu vídeo aqui se você não quiser uma dica. Agora, aqui está a sua dica. Este é o formato para instanciação e atribuição da instância a uma variável. Vamos agora escrever a solução. Tudo bem se você não sabia o que escrever. Aqui, vamos digitar a é igual a Luz e b é igual a Luz. Em seguida, deixe-me apresentar uma nova maneira de definir um atributo para sua classe. Aqui está a sua aula. Vamos definir o que é chamado de atributo de classe definindo uma variável no corpo desta classe. Vamos agora atualizar nosso código Light. Em vez de uma passagem que vamos digitar aqui é igual a False. Para acessar este atributo de classe, podemos referenciar diretamente a classe e seu atributo usando uma expressão de ponto. Pressione a “seta verde” para executar seu código. Agora, vamos usar o intérprete. O intérprete para mim está na parte inferior da tela, mas talvez no lado direito para você. Vá em frente e digite o nome da turma. Podemos ver que o padrão é False como definimos aqui. Observe que, se você definir uma instância, também poderá acessar esse atributo. Por exemplo, se escrevermos um.on obteremos False e b.on também será False. Agora é hora de apresentarmos o mistério. Vamos tentar modificar um desses atributos de Luz. Anteriormente, modificamos esses atributos em um método. Podemos modificar valores de atributo fora dos métodos também. Mude a Luz a para estar acesa. Podemos definir um.on igual a True. Como esperado se verificarmos um.on, ficaremos True. Agora, o que você acha que acontece com a Luz B, ele ainda deve estar desligado. Podemos verificar se a Luz B ainda está desligada. Agora, é hora do mistério. Vamos alterar o atributo de classe para True. Aqui vamos digitar Light.ON é igual a True. Agora, o que você acha que acontece com a Luz B? Ainda deve estar desligado, podemos verificar, mas a luz está ligada. O que aconteceu aqui? Temos que visualizar para entender o que aconteceu. Começamos definindo o atributo da classe Light para estar desligado. Em seguida, definimos uma nova instância como esperado, esta nova instância ainda está desativada. Em seguida, alteramos o atributo de classe para True para que o padrão esteja ativado. Isto é o que esperávamos que acontecesse. Esperávamos que a Luz instanciada não fosse afetada. No entanto, vimos que a Luz instanciada foi afetada. Também estava no, que é bem aqui, B.On era Verdadeiro também. Aqui está o que realmente aconteceu. Definimos o atributo de classe Light, que está desativado por padrão. Quando instanciamos a Luz, a Luz não tinha o seu próprio atributo para ligar ou desligar. Em vez disso, a ocorrência Light ainda tinha um atributo de classe. Como resultado, quando alteramos o atributo de classe, as instâncias no atributo também mudaram. Takeaway é que os atributos de classe são sempre compartilhados. Vamos agora explorar outro mistério. Vamos agora definir Light. On é igual a Falso. O que você acha que acontece com a Luz b, como você pode esperar? b também é agora False. O que acha que aconteceu com a Luz A? Se escrevermos um.on, a Luz a ainda está ligada. O que? Como é que a luz um escape do atributo compartilhado? Vamos dividir isso com outra visualização. Do lado esquerdo, imaginamos o que pensamos ter acontecido. Temos a classe em preto e as duas instâncias abaixo. Como aprendemos na seção anterior, atributos de
classe são compartilhados. Vamos usar setas em vez disso. Anteriormente, nós realmente ligamos manualmente a Luz um. Nesse caso, definir o atributo diretamente converte o atributo de classe em um atributo de instância. A luz a está agora dissociada e tem seu próprio estado. Em seguida, definimos o atributo de classe como True e definimos o atributo de classe de volta para False novamente. O tempo todo, Luz um permanece ligado e não é afetado. Takeaway é que os atributos de classe são compartilhados, mas os atributos de instância não são. Isso também nos leva a uma dica para evitar essa confusão. A dica é não modificar atributos de classe em seu programa. Isso vai poupar a dor de cabeça que ilustramos. Para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Isso conclui a lição. Na próxima lição vamos introduzir um novo conceito.
7. Conceito: abstração: Bem-vindo a outra lição conceitual, abstração. Não haverá nenhum código nesta lição. Em vez disso, discutiremos um conceito de programação orientada a objetos chamado abstração, que melhora a legibilidade e manutenção do seu código. Deixe-me explicar o que a abstração está usando nosso exemplo de sorvete. Este é o nosso slide de antes. Observe que descrevemos as expectativas de qualquer instância de sorvete que encontramos. Para qualquer instância de sorvete, sabemos o que a instância de sorvete faz e quais os dados que cada instância de sorvete tem. Por exemplo, podemos comer uma instância de sorvete. Mas, o mais importante, podemos comer uma instância de sorvete sem saber como o método de comer é implementado. A última parte é a chave. Como usuário de instâncias de sorvete, podemos abstrair e ignorar como esses métodos funcionam. Só precisamos de uma descrição aproximada do que o método faz. Chamamos essa noção de abstrair detalhes abstração. Para repetir essa definição de forma mais sucinta, a idéia de abstração é remover detalhes desnecessários para o usuário. Em nosso exemplo, o usuário é o comedor de sorvete. A pessoa que come sabe que pode comer o sorvete ou adicionar colheres. Os detalhes desnecessários de como o sorvete lida com a alimentação são abstraídos. Isso melhora a legibilidade do seu código. Agora vamos discutir o que a abstração está se escondendo. O que é essa informação desnecessária? Esta próxima seção exemplifica um conceito relacionado chamado encapsulamento. No centro temos nossos dois métodos comer e adicionar. À direita, em azul, temos descrições de métodos para usuários
externos que cada método permite que os usuários comam até que não haja mais sorvete. O método add permite que usuários externos adicionem mais sorvete. À esquerda em vermelho, temos o funcionamento interno de cada método internamente ou manter a conta para o número de colheres restantes. Não muito surpreendentemente, comer simplesmente subtrai uma colher, e adicionar simplesmente adiciona uma colher, os detalhes internos vermelhos estão escondidos longe de usuários externos. Para impor isso, usamos encapsulamento. Não vamos enfatizar muito o encapsulamento. Basta saber que no encapsulamento envolve restringir o acesso a informações internas, como impor que as colheres não podem ser modificadas por pessoas de fora. Em algum encapsulamento oculta informações do usuário. Se você está confuso sobre a diferença entre abstração e encapsulamento, tudo bem. Não saber a diferença mesmo depois de completar este curso é bom. Usar abstração e encapsulamento, seja
qual for,
é a parte importante. Agora vamos discutir um benefício da abstração, que é remover redundância no código. Essa remoção de redundância é como abstração realmente melhora a manutenção do seu código. Veja como a abstração remove a redundância. À direita, temos um sorvete. É suporta o método add, que adiciona uma colher de sorvete. À esquerda, temos um caminhão de sorvete. Faz sentido que ao encomendar no caminhão de sorvete, também
tivemos uma colher de sorvete. No entanto, e se quisermos modificar o comportamento de adição de colher? Agora, só podemos adicionar uma colher, se o número total de colheres for menor que três. Também precisamos adicionar essa restrição onde quer que adicionemos uma colher de sorvete, como no caminhão de sorvete. Em seguida, e se adicionarmos outra modificação? Se não houver mais colheres, adicione três colheres ao mesmo tempo. Também precisamos adicionar isso onde quer que adicionemos uma colher de sorvete, como no caminhão de sorvete, isso rapidamente se torna um pesadelo de manutenção. Aqui está o porquê. O que acontece quando essas duas cópias do código de adição de colher saem de sincronia? Então, o sorvete começa a se comportar de maneiras inesperadas. Você pode ter um pouco de sorvete com mais de três colheres, por exemplo. Esses comportamentos inesperados são o que causa bugs na produção, então cuidado. Mas como consertamos isso? Nós só queremos uma cópia da colher adicionando código. Simplesmente, qualquer código que adiciona sorvete deve chamar as classes de sorvete adicionar método. Ninguém mais deve modificar diretamente o número de colheres em um cone de sorvete. aplicação desta abstração nos permite reduzir a redundância no código. Dica. Verifique se há código redundante. Se você copiar colando ou gravando código redundante, você está fazendo isso errado. Vamos elaborar sobre o porquê e como quando começarmos a codificar. abstração remove informações desnecessárias. Por exemplo, você não precisa saber como a ingestão de sorvete funciona para chamar o método de comer. Isso melhora a legibilidade do seu código, tornando a compreensão mais fácil e rápida. O encapsulamento oculta ou restringe o acesso às informações. Por exemplo, você não pode acessar o número de colheres de sorvete deixadas diretamente. Finalmente, abstração remove redundância e código, subtração também melhora a manutenção do seu código. Não se esqueça da abstração. Aqui está um resumo dos conceitos que abordamos até agora. Para obter uma cópia desses slides e mais recursos, confira o site do curso. Isso conclui nossa lição, abstração. Na próxima lição, simularemos um caminhão de sorvete que implementa corretamente a abstração.
8. Prática: caminhão de sorvete: Nesta aula, nós vamos praticar a abstração criando uma aula de caminhão de sorvete. Uma vez que você vê esta página, falha o projeto para obter sua própria cópia editável. Para fazer isso, clique no nome do projeto no canto superior esquerdo para obter um menu suspenso, clique nas reticências para obter outro menu suspenso
e, finalmente, clique no botão Fork. Então eu sugiro colocar suas janelas Skillshare e responder .it lado a lado, como mostrado aqui. Você deve então ver um código semelhante ao que eu vejo à direita. Se você rolar para baixo, verá a aula de sorvete que escrevemos na última lição. O primeiro passo é alterar nossa funcionalidade add scoops. Se tivermos mais de três bolas, nosso gelado deve cair, deixando-nos com zero bolas. Dentro do nosso método add, devemos primeiro verificar se há mais de três colheres. Aqui vamos digitar se self.scoop é maior do que três,
em seguida, definir o número de colheres para zero. Nós também vamos adicionar uma declaração de impressão aqui para explicar o que aconteceu com o usuário. Aqui vamos imprimir, 'Demasiadas bolas! Derrubei sorvete. Antes de seguir em frente, aqui vai uma dica. Evite números mágicos. Números mágicos são quaisquer números escritos diretamente
no código como este três e este é zero. Zeros são simples o suficiente para raciocinar, mas por que três? Sabemos que três é o número máximo de bolas. Mas em programas mais complexos, os números
mágicos tornam-se mais difíceis de entender por outros programadores. Em vez disso, devemos substituir este três por uma variável chamada max scoops, que tem o valor três. Vamos fazer isso agora. Para a nossa variável, vamos definir um atributo de classe chamado max scoops. Vamos fazer isso agora em código. Dentro da sua aula de sorvete, vamos definir o máximo de bolas iguais a três. Podemos então usar este atributo classe abaixo em vez do número 3. Aqui vamos escrever em vez do número 3 no método add, self.max scoops. Vamos agora usar esta aula de sorvete e ver como respeitar a abstração na prática. Clique na seta verde na parte superior para executar seu arquivo. Agora, instancie seu sorvete. Então digamos que queremos adicionar colheres, podemos modificar diretamente o número de colheres, sorvete.colheres mais igual a dois. Mas lembre-se, queremos definir o número de bolas para zero. Se excedermos três bolas, podemos começar a codificar isso. Se colheres de sorvete maior que três, mas isso deve parecer familiar. Acabamos de escrever este código no método add, esta familiaridade, esta redundância, deve ser uma bandeira vermelha. Além disso, não devemos modificar o atributo scoops diretamente. Não estamos seguindo corretamente a abstração. Então, em vez disso, devemos usar o método add que já escrevemos. Aqui, em vez disso, devemos estar escrevendo sorvete cream.add (2) e aqui vamos notar que nossa funcionalidade realmente chuta. Temos mais de três bolas no sorvete agora, então caímos e só temos zero bolas. Poderíamos repetir o mesmo erro. Digamos que você deseja diminuir o número de colheres. Poderíamos digitar sorvete. Scoops menos igual a três. Mas então espere, queremos verificar se ainda há colheres suficientes antes de subtrair. Então, podemos digitar, 'Se gelado.colher menos de três”, e novamente, eles devem parecer familiares. Acabamos de escrever essa lógica no método de comer. Esta é a nossa bandeira vermelha. Devíamos usar o método de comer. Em vez de digitar isso, vamos agora escrito sorvete. Coma (3). Isso nos dará, não restam mordidas suficientes. Dica, verifique se há código redundante. Se você estiver copiando colando ou gravando código redundante, provavelmente
está fazendo isso errado, e aqui está o motivo. Ter código redundante torna o código difícil de manter. Especificamente, uma atualização para uma cópia pode não ser propagada para a outra cópia desse código. Em seguida, você tem cópias lentamente divergentes de código que ambos tentam fazer a mesma coisa, então verifique se há código redundante, certifique-se de que você está respeitando a abstração. Vamos agora delinear uma nova aula de caminhão de sorvete. Como atualização, aqui está o formato. Defina sua nova classe com o nome da classe, dois espaços e passe para o corpo da classe. Vamos definir um caminhão de sorvete de classe e passar por agora. Então defina seus métodos. Você precisará de um pedido de método para que os clientes possam pedir seus cones de sorvete. Para este método, precisamos saber quantas colheres adicionar inicialmente. Exclua “Passar” e agora adicione “Ordem” com o argumento auto e o número de colheres a serem adicionadas inicialmente. Mais uma vez, vamos digitar o passe e preencher o corpo do nosso método mais tarde. Também teremos um segundo método chamado add, que os clientes possam encomendar recargas para seus cones de sorvete. Para este método, precisamos do sorvete para adicionar dois e quantas colheres adicionar. Defina o método add, mas o auto-argumento,
e, em seguida, o sorvete para adicionar e o número de colheres a adicionar. Novamente, use pass e nós vamos preencher o método mais tarde. Vamos agora à aula de carrinhos de gelados. Dentro do método de pedido, criaremos uma nova instância de sorvete. Aqui temos sorvete igual a uma nova instância de sorvete. Agora vamos adicionar bolas a ele. Nós aprendemos nossa lição de antes, vamos usar o método add do sorvete em vez de modificar o atributo scoops diretamente. Agora digite sorvete. Adicionar e o número de colheres. Finalmente, devolva o sorvete ao cliente. Nós também terminaremos o método add. Este método é bastante simples. Adicione colheres ao sorvete, então gelado.adicione colheres. Vamos agora rastrear quantas bolas vendemos. Vamos precisar adicionar um construtor que inicializa o número de colheres vendidas a zero. Aqui vamos definir um novo construtor com o argumento auto e definir o número de colheres vendidas igual a zero. Em seguida, atualizaremos o número de colheres vendidas no método de pedido. No método de pedido, adicionaremos o número de colheres vendidas. Finalmente, no método add, vamos fazer isso mais uma vez, vamos preencher o número de colheres vendidas. Mas espere, nós acabamos de escrever esta linha de código acima. Se você comparar essas duas linhas, 37 e 38 com as duas linhas acima, 32 e 33, você verá que elas parecem idênticas. Esta é uma bandeira vermelha de novo. Temos código redundante, podemos estar quebrando abstração. Acontece que estamos. Este método adicionar para o caminhão de sorvete alças adicionando colheres para um sorvete, então devemos estar usando os caminhões de sorvete adicionar método para adicionar colheres a um cone de sorvete. Em vez disso, vamos excluir as linhas 32 e 33 e, em vez disso substituir isso por self.add colheres de sorvete. Agora estamos respeitando a abstração do nosso caminhão de sorvete. Dica, compreender o contrato que uma classe fornece pode ajudá-lo a organizar o código dentro da classe. Aqui, entender que o método add manipula a adição de colheres e a contabilização de um número de colheres vendidas significa que podemos usar esse método add em vez de fazer as duas etapas manualmente, economizando a gravação de código redundante. Vamos usar essa aula de caminhão de sorvete. Aprendendo com nossos erros anteriores, sabemos agora respeitar a abstração. Novamente, pressione a seta verde na parte superior do seu arquivo para executar o código. Note-se que agora existe um novo nível de abstração. Não devemos criar ou adicionar cones de sorvete diretamente, em vez disso, devemos pedir do caminhão de sorvete. Vamos agora criar um novo caminhão. Peça sorvete com três colheres. Aqui temos sorvete um é igual a caminho.ordem com três colheres de sorvete,
em seguida, comer um pouco do sorvete. Agora vamos pedir ainda mais sorvete do caminhão. Vamos digitar o caminhão. Adicione um sorvete e adicione uma colher. Vamos ver quantas bolas os caminhões de sorvete venderam. Parece bom. O pedido inicial era de três colheres e adicionamos mais uma colher, totalizando quatro colheres vendidas. Para obter uma cópia desses slides e o código finalizado para esta lição, certifique-se de conferir o site do curso. Nesta lição, abordamos algumas práticas de abstração usando um caminhão de sorvete. Em particular, você viu como eu falhei em usar abstração e como corrigir isso. Lembre-se das três dicas desta lição, evite números mágicos, verifique se há código redundante e seja claro sobre as expectativas. A próxima lição é prática bônus.
9. Prática (bônus): luzes sincronizadas: Nesta lição, vamos praticar mais do conceito de abstração que discutimos. Desta vez, vamos construir nossa simulação de luz sincronizando alguns dos interruptores de luz. Navegue até este URL para começar. Depois de ver esta página, o
fork do projeto para obter sua própria cópia editável. Para fazer isso, clique no nome do projeto no canto superior esquerdo para obter um menu suspenso. Clique nas reticências para obter outra lista suspensa e, finalmente, clique no botão Fork. Então sugiro colocar suas janelas Skillshare e Repl.it lado a lado, como mostrado aqui. Antes de começarmos, quero introduzir um novo conceito que você ainda não viu, um argumento padrão no Python. Vamos começar definindo uma função de subtração. Como lembrete, aqui está o formato para definir uma função. Por uma vez, este slide de formato é na verdade o código exato que vamos escrever. Vamos escrever o nosso código agora. Seu código no lado direito deve coincidir com o meu. Se você rolar para baixo, verá a classe de luz que definimos nas lições anteriores. Logo acima desta classe de luz, vamos definir o sub método que vemos no lado esquerdo. Vá em frente e digite fora, defina sub (x, y) e retorne x menos y. Vamos agora usar esta função objetivo. Vamos chamar o submarino com entrada sete e quatro. Vá em frente e aperte a seta verde no topo para executar o seu código. Então digite submarino 7, 4 para obter três. Agora, o que acontece se você esquecer o segundo argumento? E se escrevermos submarino sete e apertarmos “Enter”? Bem, você receberá um erro e seu erro ficará assim. Diz que está perdendo seu segundo argumento. Vamos definir outra função de subtração sub dois. Desta vez vamos atribuir y um argumento padrão de zero. Vamos escrever o nosso código agora. Vamos definir sub2 x, mas agora nós digitamos y igual a zero e tudo o resto permanece o mesmo. Este sinal de igual na definição da função dá y um valor padrão. Nem sempre atribui y a zero. A função só atribui y a zero se você não der um segundo argumento de entrada. Vamos ver isso em ação. Primeiro, execute o arquivo pressionando a seta verde no topo. Vamos ver o que acontece quando passamos os dois argumentos como antes. Digite sub2 7, 4 e como esperado, temos três. Aqui, x é atribuído a sete e y é atribuído a quatro. Agora, vamos ver o que acontece se passarmos em apenas um argumento. Digite sub2 7 e acontece que não há erro e tiramos sete. O que aconteceu aqui? Isso ocorre porque x foi atribuído a sete e y foi automaticamente atribuído a zero. Temos 7 menos 0. Vamos agora cobrir um conceito relacionado chamado argumentos de palavra-chave. Isso é melhor explicado pelo exemplo. Vamos executar novamente a versão anterior com dois números de entrada. Aqui teremos sub2 7,4. Aqui, sete é atribuído a x e a segunda entrada quatro é atribuída a y. você aperta “Enter”, obtemos 7 menos 4 que é 3. Nós também podemos dizer explicitamente Python qual entrada é x e qual entrada é y. aqui nós podemos digitar em sub2, x é igual a sete e y é igual a quatro. Podemos apertar “Enter” e ainda temos três. Chamamos estes x igual a sete, y é igual a quatro argumentos de palavra-chave. Você pode especificar argumentos de palavra-chave em qualquer ordem. Aqui podemos mudar o x e os argumentos da palavra-chave y sub2, y é igual a quatro, x é igual a sete. Aperte “Enter” e ainda ganhas três. Observe que se você não usar argumentos de palavra-chave e alternar as entradas, então você terá algo diferente. Vou limpar minha saída para que você possa ver a parte inferior da minha tela e aqui vamos digitar sub2 4, 7 alternando a ordem sem usar argumentos de palavra-chave e aqui a saída é diferente. Nós obtemos negativo 3 porque agora temos 4 menos 7 em vez de 7 menos 4. Agora que você abordou argumentos padrão e argumentos de palavra-chave, vamos usá-los em nossa nova classe. Agora vamos finalmente trabalhar no conceito de abstração. Vamos adicionar a capacidade de sincronizar duas luzes para que alternar como Número 1 também alterne como Número 2. Vá em frente e role para sua classe de luz. Vamos adicionar um argumento para o construtor chamado sync. Este argumento terá um valor padrão de nenhum com um N. None maiúsculo apenas significa vazio. A intenção é definir a sincronização com outra luz para sincronizar. Verá o que quero dizer em um segundo. Aqui vamos definir luz após a sincronização de vírgula de auto-argumento é igual a nenhum. Podemos então definir a sincronização argumento de entrada como um atributo instanciado também chamado sincronização. Aqui vamos escrever self.sync igual a sincronizar. Vamos agora usar o atributo sync se ele não estiver vazio ou, em outras palavras, se o atributo sync não for nenhum, então alterne a sincronização para a luz. Vá em frente e role para baixo até seu método de alternância. Aqui vamos digitar se a sincronização self.sync não for nenhuma, então alterne a luz de sincronização. Aqui você pode ser tentado a simplesmente alternar a luz de sincronização escrevendo em self.sync.on é igual a não self.sync.on. No entanto, você estaria quebrando abstração. E se essa luz estiver sincronizada com outra luz? Então teríamos que verificar se self.sync.sync não é nenhum e assim por diante e assim por diante. Isso é um código redundante. Então, como sempre, código redundante é uma grande bandeira vermelha. Em vez disso, temos que respeitar a abstração, self.sync como uma luz e podemos alternar luzes chamando seu método de alternância. Em vez disso, vamos escrever self.sync.toggle. Isso conclui nossas luzes sincronizadas. Agora, vamos instanciar e usar a luz sincronizada. Vá em frente e acerte a seta verde no topo para executar seu código e agora vamos instanciar nossa primeira luz. Luz 1 é igual à luz. Instancie sua segunda luz, mas desta vez defina o argumento de entrada de sincronização para a primeira luz. Isso garante que, se alternarmos a luz Número 2, luz Número 1 também alterna. Aqui definir luz Número 2 é igual a luz, definir sincronização igual à primeira luz. Vamos ver se a luz número um está acesa. Vamos digitar light1. está ligado. Parece que a nossa primeira luz não está acesa. Agora, vamos alternar a luz Número 2.Isso deve ativar tanto a luz Número 1 quanto o Número 2. Aqui temos light2.toggle e vamos verificar se a luz Número 1 está agora ligada. A Luz Número 1 está ligada e agora está ligada. Ótimo, funciona. Para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Isso conclui nossa prática adicional de abstração.
10. Conceito: herança: Bem-vindos a outra lição conceitual, herança. Para entender a herança, precisamos entender um relacionamento “é”. Por exemplo, o sorvete é um exemplo de comida. Sabemos disso porque você pode comer e comer sorvete. No entanto, o sorvete também pode ter alguns métodos extras que outros alimentos podem não, como derreter. Como o sorvete é um exemplo de comida, definimos sorvete como uma classe infantil de alimentos. Também podemos dizer que o sorvete é subclasse como alimento. Chamamos comida de classe dos pais. Definir este “é um” relacionamento nos dá um benefício interessante chamado herança. Agora, aqui está como a herança funciona. Para todos os alimentos, esperamos ter o método de comer. Uma vez que o sorvete é uma classe infantil de alimentos, sorvete herda automaticamente o método de comer. Você pode adicionar tantas classes infantis de alimentos como você quiser e todos eles herdarão a mesma funcionalidade comer. Vamos repetir esta análise com outro exemplo. Um caminhão de sorvete é um caminhão. Em particular, um caminhão de sorvete tem todas as propriedades que um caminhão tem e muito mais. Como resultado, definimos caminhão de sorvete para ser uma classe infantil de caminhão. Isso nos dá um bom benefício. Esperamos que todos os caminhões tenham a funcionalidade ou o método de acionamento. Desde caminhão de sorvete é uma classe infantil de caminhão, ele herda o método de condução também. Finalmente, caminhão de sorvete pode ter alguns métodos adicionais que outros caminhões não têm, como ordem. Em resumo, A é um B se A tem todas as propriedades que B tem; por exemplo, sorvete é um alimento. Como o sorvete tem todas as propriedades dos alimentos, isso significa que o sorvete herda toda a funcionalidade dos alimentos. Por padrão, comer sorvete é como comer qualquer outro alimento. No entanto, e se isso não for verdade? E se comer sorvete for drasticamente diferente de comer outros alimentos? Em outras palavras, queremos substituir a funcionalidade herdada padrão. Este é o nosso próximo conceito em herança, substituto. Anteriormente, dissemos que o sorvete herdaria o método de comer dos alimentos já que o sorvete é um alimento. No entanto, digamos que a ingestão de sorvete é única e ao contrário da ingestão geral de alimentos. Nós precisaríamos substituir o método de comer, definindo um método de comer personalizado para sorvete especificamente. Talvez queiramos substituir o comer porque representamos a quantidade consumida de maneiras diferentes. Com sorvete, medimos a quantidade restante em colheres. Com outros alimentos, usamos uma porcentagem. Em resumo, a classe filho herda o método de uma classe pai por padrão. No entanto, a classe filho pode substituir ou redefinir esses métodos. Estes dois conceitos são os principais aspectos. Vamos cobrir os dois últimos conceitos bônus depois de um breve resumo do que aprendemos até agora. Nosso primeiro conceito, o “é uma” relação, nos
diz quais classes subclasses umas às outras. Uma vez que o sorvete é comida, sorvete subclasses alimentos. sorvete então herda métodos dos alimentos. No entanto, também podemos ter sorvete substituir métodos herdados de alimentos, se necessário. Para obter uma cópia desses slides e mais recursos, certifique-se de conferir o site do curso, e isso conclui nossa lição sobre herança. Havia um monte de idéias chave nesta lição, mas os passos mais importantes ou o “é um” relacionamento e imperativo. Não se preocupe se os detalhes estiverem enlameados. Vamos tornar essas ideias mais concretas na próxima lição, quando começarmos a codificar. Agora vamos cobrir mais dois breves conceitos bônus. Se você estiver se sentindo sobrecarregado ou não quiser conteúdo bônus agora, fique à vontade para pular para a próxima lição. Uma interface, como a interface alimentar à direita, simplesmente delineia as expectativas, mas não fornece implementações padrão. Aqui, o alimento especifica um método de comer e adicionar, mas na verdade não implementa também. sorvete implementa a interface alimentar com implementações utilizáveis para ambos os métodos. Nosso último conceito é um abstrato. Um resumo também define expectativas para uma subclasse. No entanto, ele pode implementar alguns métodos e deixar outros métodos não implementados. Aqui, o resumo alimentar implementa o método eat e especifica um método add sem implementá-lo. Sorvete subclasses o alimento abstrato e preenche a implementação do método add, e isso conclui a lição sobre herança, incluindo os conceitos de bônus. Na próxima lição, começaremos a codificar alguns desses conceitos de herança.
11. Prática: caminhão de sorvete de luxo: Para praticar Herança, vamos fazer um DeLuxeiceCreamTruck. Este DeluxeiceCreamtruck, dá-lhe uma colher livre com o seu pedido de sorvete. Navegue até este URL para começar. Depois de ver esta página, o
fork do projeto para obter sua própria cópia editável. Para fazer isso, clique no nome do projeto no canto superior esquerdo para obter um menu suspenso. Clique em “Elipsis” para obter outro menu suspenso. Finalmente, clique no botão “Fork”. Então, sugiro colocar suas janelas Skillshare e responder .it lado a lado, como mostrado aqui. Você vai pular direto para escrever uma subclasse. Aqui está o formato. Temos nossa definição de classe normal, exceto que incluímos a classe pai em roxo entre parênteses, como vemos aqui. Neste exemplo, ice é a classe filho e H_2O é a classe pai. Vamos usar este formato para o nosso DeLuxeiceCreamTruck agora. Depois de bifurcar o outro repl.it, você deve ver o código como o meu à direita. Por baixo de todo o código existente, vamos agora definir o nosso DeLuxeiceCreamTruck. Primeiro, crie a classe DeluxeiceCreamTruck, seguida, subclasse caminhão de sorvete, como discutimos, em
seguida, subclasse caminhão de sorvete, como discutimos,
digite a classe DeluxeiceCreamTruck, e subclasse o caminhão de sorvete com dois pontos. Podemos adicionar passar aqui como um espaço reservado. Agora, você precisará substituir o método de pedido, uma vez que o DeluxeiceCreamTruck oferece uma colher gratuita a cada pedido. Este é o formato para definir um método. Substituir um método não usa nenhuma sintaxe especial. Basta redefinir o método na classe filho. Aqui vamos definir seu método de pedido. Exclua a aprovação e defina a ordem. Novamente, você precisa de si mesmo como o primeiro argumento e aceita um argumento, scoops. Como antes, criamos um novo sorvete. Em seguida, chamamos o método self.add, e passamos em número de colheres. Mas espere, isso é exatamente como antes. Esta é a sua bandeira vermelha. Como temos dito, código redundante significa que algo está errado. Como podemos reutilizar nosso método original de pedido acima? Estamos interessados especificamente em chamar nosso método de classe pai. Veja como fazer isso. Para chamar o método da classe pai, basta usar a super instância. Deixe-me mostrar-lhe em código agora. Vamos ligar para a Super.Order e passar o argumento do Scoops. Aqui vamos em vez dessas duas linhas digite super.order e passar em colheres. Aqui, isso chama a ordem do método pai. Este método retorna a instância de sorvete. Então, defina essa instância como uma variável. Aqui teremos sorvete igual a super.ordem. Em seguida, adicionaremos uma colher de sorvete grátis sem atualizar o número de colheres vendidas. Aqui vamos escrever, ice_cream.add1. Caso esteja se perguntando, por que não usamos o método de adição de caminhões de sorvete? O método add que foi herdado da classe pai. No entanto, não usamos o método de adição de caminhões,
porque o método de adição de caminhões também atualiza o número de colheres vendidas. Neste exemplo específico, estamos dando uma colher livre de sorvete e não queremos atualizar um número de colheres vendidas. É assim que temos sorvete. Add1. Finalmente, devolva o sorvete ao cliente. Uma nota rápida. Uma boa prática é sempre invocar o construtor de classe pai em seu próprio construtor. Vamos fazer isso agora para outros construtores agora. Aqui no construtor do caminhão de sorvete, vamos chamar super.init. Então vamos repetir isso mais uma vez para a aula de sorvete. Para o último segmento desta lição, use a ocorrência de DeluxeiceCreamTruck. Vamos clicar no botão verde na parte superior para executar nosso código. Primeiro, instancie o DeLuxeiceCreamTruck. Aqui vamos ter caminhão é igual a DeLuxeiceCreamTruck. Então vamos pedir um sorvete com duas colheres, sorvete é igual a caminho.order2, e boom, o sorvete que temos agora tem três colheres. Ele inclui a única colher livre que adicionamos. Podemos verificar escrevendo “ice_cream.scoops “, e temos três bolas. Também podemos verificar quantas bolas o caminhão de sorvete vendeu. Aqui vamos digitar caminho.vendido, e esperamos apenas dois. Como esperado, temos dois. O caminhão só vendeu duas bolas, e a terceira foi grátis. Para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Isso conclui a prática de DeLuxeiceCreamTruck para Herança. A próxima lição é uma lição de prática bônus para construir familiaridade com essas idéias.
12. Prática (bônus): luz piscante: Nesta lição, vamos praticar herança mais uma vez. Desta vez, faremos uma velha luz que pisca toda vez que você ligar. Navegue até este URL para começar. Depois de ver esta página, o
fork do projeto para obter sua própria cópia editável. Para fazer isso, clique no nome do projeto no canto superior esquerdo para obter um menu suspenso. Clique em “Elipsis” para obter outro menu suspenso
e, finalmente, clique no “Fork”. Então sugiro colocar suas janelas Skillshare e Repl.it lado a lado, como mostrado aqui. Nós vamos direto na subclasse nossa classe de luz original. Aqui está o formato para definir uma subclasse. Em seu código, você deve ver uma classe de luz que definimos na lição anterior. Role para baixo até a parte inferior do seu arquivo. Aqui vamos definir uma luz antiga que subclasses a classe de luz original. Vamos digitar passe aqui por agora. Agora você substituirá o método de alternância na classe pai já que nossa luz precisa piscar a cada outra vez que a luz é acesa. Vamos agora definir o nosso construtor que define cintilação como falso. Isso significa que o padrão para todas as luzes será não cintilar iniciando. Defina o construtor com o argumento self com sincronização igual a nenhum. Lembre-se que este argumento padrão estava em nosso construtor de classes originais. Vamos então precisar escrever em é igual a false. Assim como antes, vamos escrever sincronização é igual a sincronização. Essas duas linhas parecem redundantes, e você está certo, elas são, isso deve ser uma bandeira vermelha, vamos ajustar isso em um segundo. Finalmente, vamos definir a cintilação como false, dessa forma a luz não está piscando por padrão. Agora você substituirá o método de alternância na classe pai, já que nossa luz precisa piscar cada vez que a luz for acesa. Aqui está o formato para definir um novo método. Logo abaixo do nosso construtor, vamos agora definir um método de alternância. Como antes, precisamos mudar a luz de ligada para desligada ou de desligada para ligada. Vamos escrever aqui self.on é igual a não self.on. No entanto, precisamos então verificar a luz sincronizada. Se o self.sync não é nenhum, isso deve parecer suspeito. Temos um código redundante. Esta é uma bandeira vermelha. Este código simplesmente repete o método de alternância do pai. A solução é chamar o método pai. Precisamos chamar o método pai. Veja como chamar o método pai. Nós simplesmente usamos a super instância como um substituto para nossa instância pai. De volta ao seu código, vamos realmente excluir essas duas linhas e, em vez disso, escrever super () .toggle (). Antes de continuar, vamos precisar realmente chamar o construtor pai de todos os outros construtor classes. Aqui, precisamos chamar o construtor pai. O construtor pai realmente leva em um argumento de sincronização. Na luz original, também
chamaremos seu construtor pai. Agora, podemos terminar o método de alternância. Verificamos se a luz está acesa. Se for, alterne a luz piscando ou não, dessa forma a cada outra vez que a luz está piscando. Se a luz estiver acesa, então mudamos se está piscando ou não. Isso completa nossa velha luz cintilante. Finalmente, vamos usar esta luz velha. Vá em frente e clique na seta verde na parte superior para executar seu código. Então instancie sua velha luz. A luz é igual à luz antiga (). Verifique se está piscando ou não, light. Flicker. Na verdade, não está piscando. Vamos agora acender a luz. Vamos verificar se a luz está piscando agora. Deveria ser e na verdade está piscando. Vamos desligar a luz e depois acender novamente, e vamos verificar novamente se a luz está piscando. Desta vez, não deveria ser. Na verdade, não está piscando. Para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Isso conclui nossa prática para o conceito de herança usando velhas luzes cintilantes. Na próxima lição, falaremos sobre um erro misterioso na programação orientada a objetos, por que isso acontece e como corrigi-lo.
13. Mistério (bônus): MRO: Nesta lição, abordaremos erros misteriosos em Python. Este erro é devido a um conceito chamado ordem de resolução de método. Como antes, note que esses mistérios abordaram algumas das partes mais confusas do OOP. Se você está se sentindo sobrecarregado, sugiro pular essas sessões misteriosas na primeira passagem para este curso, revisitando-as em uma segunda passagem. Assim como antes, navegue para responder. it/languages/python3, já que começaremos do zero. Então sugiro colocar suas janelas Skillshare e Repl.it lado a lado, como mostrado aqui. Primeiro, deixe-me explicar um conceito chamado herança múltipla. Antes, vimos que uma classe pode subclasse outra classe. Por exemplo, sorvete poderia subclasse alimentos, porque sorvete é um tipo de alimento. E se o sorvete também for uma bebida? Porque o sorvete pode derreter? Então podemos querer sorvete para subclasse comida e bebida. Vamos ver o que isso parece em código. Este é o formato. Aqui, classe C subclasses A e B. Para ler isso, leia da esquerda para a direita. Métodos em C pode substituir métodos em A. Métodos em A pode substituir métodos em B. Apenas para manter o controle, vamos resumir isso como A maior do que B, significa que A tem precedência sobre B usando esta notação acima. Vamos agora introduzir o erro misterioso. Aqui está o formato novamente. Vamos codificá-lo. Criar classe A com um corpo de espaço reservado. Em seguida, crie uma segunda classe B, que
subclasse é A. Classe B subclasse A e um espaço reservado para o corpo. Finalmente, crie uma terceira classe C, que subclasses A e B. Certifique-se de escrever suas classes exatamente nesta ordem. A, B, depois passe para o espaço reservado. Agora tente executar seu código usando a seta verde, execute no topo. Aqui está o erro misterioso, erro de resolução de método. O que isso significa e como isso aconteceu? Vamos quebrar isso. Para entender esse erro, precisaremos visualizá-lo. Primeiro, subclasses B A nas linhas 4 e 5. B tem precedência sobre A. Denotamos isso como B maior que A. No entanto, C subclasses A e B, como escrevemos aqui. De acordo com a nossa notação, A ,
B, isto significa que A tem precedência sobre B. Vamos denotar isto como A maior que B. Esta é a contradição. B é maior que A e ainda A é maior que B, então qual deles, A ou B tem precedência? Isto é o que Python está reclamando. Não sabe qual classe tem prioridade. A próxima pergunta natural é, como resolvemos isso? Reexaminando a visualização que vimos anteriormente, podemos realmente remover qualquer um desses erros para corrigir o problema. Mas um desses erros é mais fácil de remover do que os outros. Podemos redefinir A e B para que B não subclasse A. Isso requer uma mudança de paradigma em como entendemos a herança. Na próxima lição, discutiremos exatamente o que é essa mudança de paradigma. Por enquanto, para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Isso conclui um mistério de ordem de resolução de método. Discutimos quando o erro acontece, por que isso acontece e introduzimos uma maneira de corrigir o problema. Na próxima lição, abordaremos isso corrigido com mais detalhes.
14. Conceito: herança+: O objetivo desta lição é colocá-lo à frente
da curva para tornar seu código muito mais flexível do que outros. Existem dois conceitos que irão aprofundar sua compreensão de programação orientada a objetos, mixins e composição. Anteriormente, falamos muito sobre o “é um” relacionamento em herança. Um paradigma comum é dizer, por exemplo, que um ônibus é um veículo, é transporte. Mas o que acontece quando você tem um ônibus que foi convertido em um lar? Ainda é um ônibus, mas não é mais um veículo. Nesta lição, vamos refinar nossa compreensão de herança em programação orientada a objetos. Para entender por que precisamos de refinação, vamos mergulhar no problema da elipse do círculo. Esta seção exigirá que você pense muito e
depende muito de sua compreensão das lições anteriores. Se precisar, pegue água ou faça uma pausa para esticar primeiro. Primeiro, lembre-se da escola que um círculo é uma elipse. Para refrescar sua memória por isso: uma elipse tem dois eixos, onde cada eixo pode ter um comprimento diferente. Um círculo é um caso especial em que ambos os eixos têm o mesmo comprimento. Então, um círculo é um tipo especial de elipse. Dizemos que um círculo é uma elipse. No entanto, lembre-se de nossa regra “é uma” da lição de herança. A é um B se A tem todas as propriedades que B tem. Conectando o que sabemos, um círculo é uma elipse, uma
vez que um círculo tem todas as propriedades que a elipse tem? Espera aí, isso parece muito errado. Círculos não têm todas as propriedades que uma elipse tem. Um círculo tem apenas um comprimento de eixo; uma elipse tem dois comprimentos de eixos. Se você realmente pensar sobre isso, uma elipse tem todas as propriedades que um círculo tem. Portanto, uma elipse é um círculo. Então nossos professores estão errados? Acontece que isso também não está certo. Um círculo tem um raio, mas uma elipse não. elipses também não têm todas as propriedades de um círculo. Então eu suponho que um círculo não é uma elipse, e uma elipse não é um círculo, pelo
menos de acordo com a relação “é uma” em herança. Nossa solução é usar um paradigma diferente chamado mixins. Penso nisso como a relação “pode”. Deixa-me mostrar-te o que quero dizer. Aqui estão duas classes, pessoa e cão. Abaixo de ambas as classes, listei os métodos deles. Começaremos usando herança. Nossa classe natural de pais é coisa viva, que define mover e crescer por padrão. Aqui, o texto cinza sob pessoa e cão significa que essas duas classes herdam esses métodos. No entanto, e se adicionarmos uma classe de carro? Um carro não é uma coisa viva, mas pode se mover. Vamos criar outra classe pai para classes que podem se mover. Esta nova classe é chamada de móvel, e tanto o ser vivo quanto o carro herdam dela. Ótima. Mas e se tivéssemos uma aula de plantas? É uma coisa viva, mas não se move. Não há hierarquia clara onde isso funcionará. Então, em vez de construir uma hierarquia usando herança, vamos considerar o que cada classe é capaz de fazer. Cada classe pai, em vez disso, define uma propriedade do objeto. Aqui, temos uma classe pai para todas as classes que podem crescer, chamado Crescível, em rosa. Também temos uma classe separada, chamada Movable, em azul. Cada classe pai define um novo comportamento que as subclasses podem fazer. Uma planta pode crescer, uma pessoa pode se mover e crescer, e assim por diante e assim por diante. Em resumo, A pode B se um tem a capacidade B; por exemplo, uma pessoa é crescível desde que uma pessoa pode crescer. O nome oficial para essas classes baseadas em habilidades são mixins, que melhoram muito a flexibilidade do seu código. Você pode misturar e combinar qualquer número de habilidades diferentes para cada nova classe que você definir. Outra alternativa para a relação “é uma” é a composição, onde nós aninhamos objetos em vez de herdar objetos. A composição é resumida por “tem um” relacionamentos, como como a forma como um carro tem rodas. Eu acredito que a composição tem mais nuance do que a maioria dos artigos on-line cobrem, mas vamos parar aqui por agora porque eu sinto a nuance vai ser mais confuso do que útil. Vamos abordar a nuance de como a composição substitui herança em uma aula, postagem ou vídeo posterior. Nosso conceito final nesta lição é polimorfismo. Em suma, polimorfismo é quando várias classes implementam a mesma interface. Em outras palavras, um conjunto de classes satisfaz todas as mesmas expectativas. Por exemplo, podemos implementar várias classes de animais, como macaco e cão, que todos têm métodos de crescimento e movimento. Digamos que você tem um pedaço de código que só depende dos métodos de crescimento e movimento, então o legal é que você poderia executar esse código em qualquer classe animal que você tem. Isso conclui nossos conceitos para esta lição. Em suma, cobrimos o problema de elipse circulo-elipse para revelar uma falha nos relacionamentos “é um”. Em seguida, cobrimos dois tipos alternativos de relacionamentos, “pode” e “tem um” relacionamentos, para melhorar a flexibilidade do seu código. Finalmente, discutimos brevemente um benefício da programação
orientada a objetos, que é o polimorfismo. Para obter uma cópia desses slides e mais recursos, confira o site do curso. Isso conclui nossa lição avançada de herança, aumentando seu entendimento de programação orientada a objetos. Essa foi uma lição desafiadora, então se você não seguiu, tudo bem. As dicas e conclusões desta lição farão mais sentido à medida que você começar a usar programação orientada a objetos e começar a correr em falhas de design você mesmo. Na próxima lição, vamos implementar mixins.
15. Prática: derretimento de sorvete: Nesta lição, vamos implementar sorvete de derretimento. Em particular, vamos usar o conceito de mixin que aprendemos para criar um sorvete de derretimento que podemos comer e beber. Navegue até a seguinte URL para começar. Depois de ver esta página, o
fork do projeto para obter sua própria cópia editável. Para fazer isso, clique no nome do projeto no canto superior esquerdo para obter um menu suspenso. Clique nas reticências para obter outro menu suspenso
e, finalmente, clique no botão Fork. Então sugiro colocar suas janelas Skillshare e Repl.it lado a lado, como mostrado aqui. Vamos começar visualizando o objetivo. Agora, você só tem aula de sorvete. Nosso objetivo é adicionar limonada e sorvete derretido. Sabemos que o sorvete derretido deve subclasse de sorvete. No espírito dos mixins, adicionaremos uma classe potável, que adiciona a habilidade de uma classe ser bêbada. Aqui, tanto a limonada quanto o sorvete de derretimento podem ser bebidos. Destacadas em vermelho são as aulas que vamos implementar. Aqui está uma coisa a observar, no entanto. Note-se que o sorvete e potável ambos têm o método add. Precisaremos tomar cuidado especial ao usar herança múltipla de sorvete derretido. sorvete derretido precisa subclasse tanto potável quanto sorvete, mas dar precedência ao sorvete. Agora você criará essas classes uma a uma. No lado direito, você verá o código que recebemos de lições anteriores. Podemos encontrar a aula de sorvete rolando para baixo. Também podemos encontrar a aula de caminhão de sorvete,
e finalmente, a classe de caminhão de sorvete de luxo. Na parte inferior depois dessa aula, vamos agora adicionar nossos mixins. Vamos criar nossa aula potável. No construtor, defina o número de copos para zero. Vamos medir quanto da bebida é deixada em copos. Aqui está o nosso construtor com auto como um argumento, vamos definir copos iguais a zero. Em seguida, crie um método de adição que adicione um certo número de xícaras à bebida. Você tem def, o método add com este argumento auto,
em seguida, o número de xícaras para adicionar. Então vamos incrementar o número de copos por esta quantidade. Finalmente, crie um método de bebida que subtrai um certo número de xícaras da bebida. Aqui teremos o método de bebida, que leva um certo número de xícaras e deduz esse número de xícaras do total. Agora vamos voltar para os slides. Para sua referência, aqui está o diagrama para o que estamos construindo. Agora crie a aula de limonada. Novamente, para sua referência, aqui está o nosso diagrama. Debaixo do seu código existente, vamos criar uma nova aula de limonada. Esta aula de limonada herdará de beber. Esta aula de limonada será uma subclasse potável. A classe de limonada herda automaticamente todos os métodos de adicionar e beber. Agora, para a peça final, você vai implementar sorvete derretido. Mais uma vez para sua referência, aqui está o nosso diagrama. Crie uma classe, derretendo sorvete que herda de sorvete e bebível. Aqui teremos sorvete derretido que herda tanto do sorvete quanto do potável. Observe que a ordem é importante. Escrevendo sorvete primeiro, nós impomos que o método add do sorvete tem precedência sobre o método add do drinkable. Agora vamos adicionar um método elapse. Este método irá atualizar o número de colheres de sorvete não derretido e xícaras de sorvete derretido ao longo do tempo. Este método leva tempo decorrido como um argumento. Aqui vamos escrever decorrido (self), a quantidade de tempo decorrido, e primeiro calcular o número de colheres de sorvete que derreteram. Esta é a quantidade de tempo decorrido ou o número de colheres restantes; o que for menor. Aqui vamos calcular derretido é igual
ao mínimo de um tempo decorrido ou o número de colheres restantes. Em seguida, subtraia o número de colheres derretidas do número total de colheres. Aqui teremos colheres menos iguais a derretidas. Além disso, adicione o número de colheres derretidas às xícaras de sorvete derretido. Aqui teremos copos mais iguais a derretidos. Isso completa nossa aula de sorvete derretido. Os métodos de adicionar, beber e comer são todos herdados das duas classes pais. Agora você vai usar sua nova aula de sorvete derretido. Clique na seta verde na parte superior para executar seu código,
em seguida, instanciar seu sorvete derretido. Adicione algumas colheres e, em seguida, passou o tempo para ver o quanto derreteu. Aqui vamos escrever ice_cream.elapse (2). Vamos ver quantas bolas sobraram. Esperamos que duas colheres de sorvete derreta então apenas uma colher de sorvete deve ser deixada, e de fato vemos uma. Agora vamos ver quantas xícaras de sorvete derretido sobraram. Ice_cream.cups e esperamos dois, assim como nossos resultados dizem. Vamos beber sorvete derretido. Sorvete. Beba, e vamos beber um copo. Vamos agora verificar quanto sorvete derretido resta. Ice_cream.Copos, como esperado, só temos um copo sobrando. É isso. Para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Isso conclui nossa prática de sorvete derretido. Em seguida, é a prática de bônus adicional para mixin.
16. Prática (bônus): luzes cronometradas: Nesta aula, vamos praticar mais
do conceito de herança de mixin usando interruptores de luz. Em particular, vamos implementar luzes cronometradas, que desligam após um certo período de tempo. Navegue até a seguinte URL para começar. Depois de ver esta página, o
fork do projeto para obter sua própria cópia comestível. Para fazer isso, clique no nome do projeto no canto superior esquerdo para obter um menu suspenso. Clique em “Elipsis” para obter outro menu suspenso
e, finalmente, clique no botão “Fork”. Então sugiro colocar suas janelas Skillshare e Repl.it lado a lado, como mostrado aqui. Primeiro, visualizaremos nosso plano. Já temos luz. Vamos agora criar um TimerLight, que subclasses tanto um temporizador e uma luz. Observe que não criamos uma classe de dispositivo genérica que contenha todas essas habilidades. Em vez disso, ele criou temporizador separado e classes de luz, onde cada um representa uma habilidade como um mixin. Destacadas em vermelho, são as novas classes que precisaremos criar. Vamos começar com uma aula de temporizador. Aqui está o nosso diagrama do que estamos criando. Depois de bifurcar seu código, seu lado direito deve coincidir com o meu. Se eu rolar para baixo, você verá a classe de luz que criamos nas lições anteriores, bem
como a luz antiga. Na parte inferior do seu arquivo, agora
vamos criar um temporizador. Aqui temos um temporizador de classe. Em nosso construtor, vamos definir o tempo restante para zero. Defina seu construtor, e dentro do construtor, vamos definir o tempo restante para ser zero. Em seguida, defina um método conjunto que lhe permite iniciar o temporizador. Vamos definir conjunto, que leva em um argumento com quanto tempo resta. Aqui, vamos definir um tempo restante para o tempo solicitado. Em seguida, definimos um anel método para tocar quando o tempo acabou. Vamos definir anel, que não leva argumentos adicionais e irá imprimir, “Timer está para cima.” Finalmente, vamos definir um método elapse, que decorre o temporizador por algum tempo. Aqui vamos ter definido elapse, que leva em si como seu primeiro argumento e, em seguida, o tempo decorrido. Primeiro, verifique se há algum tempo restante no temporizador. Se self.left for maior que zero
, subtraia o tempo restante. Aqui temos o tempo restante é igual ao tempo restante menos o tempo decorrido. No entanto, temos de nos certificar de que esta quantidade não é negativa. Em outras palavras, se o tempo decorrido for maior do que o tempo restante, pode ser negativo. Vamos escrever aqui, max com zero, e isso garante que o tempo restante seja sempre não-negativo. Finalmente, se não houver mais tempo no temporizador, então devemos ligar. Se self.left é igual a zero, então devemos chamar o nosso método anel. Agora, devemos escrever nossa aula de TimerLight. De volta ao seu código, vamos criar uma classe TimerLight. Aqui teremos TimerLight, que herda da luz e do temporizador. A primeira coisa que faremos, aqui está nosso diagrama do que estamos criando. Crie sua classe TimerLight e subclasse luz e temporizador. Aqui teremos TimerLight, com subclasses luz e temporizador. Nosso primeiro passo será substituir o método set. Definir conjunto, que leva no tempo restante. A primeira lição aqui é respeitar as barreiras da abstração. Vamos chamar as classes pai, definir o método. Agora, se sobrar algum tempo, acenda a luz. Se self.left é maior que zero, devemos ligar automaticamente a luz. Também devemos substituir o método do anel. Aqui vamos definir anel, que não leva em argumentos adicionais, chamar o método do anel pai, possamos tocar o temporizador, e depois desligar a luz, uma vez que o temporizador só toca quando o tempo está para cima. Isso conclui nosso TimerLight. Finalmente, usaremos nossa classe TimerLight. Clique no botão verde na parte superior para executar o código e,
em seguida, instanciar o temporizador. Aqui vamos começar o relógio com cinco segundos. Temporizador ajustado, cinco. Então vamos passar três segundos. Nenhum toque deve ocorrer e nenhum ocorre. Então precisamos passar mais três segundos. Desta vez, deve tocar. Além disso, o tempo restante deve ser zero. Vamos verificar temporizador.left é de fato zero e não negativo. Em seguida, vamos verificar o nosso TimerLight. Vou clicar neste botão X para limpar minha saída. Agora, instancie sua aula de temporizador. Timer_light é igual a TimerLight. Faça exatamente a mesma coisa. Comece o relógio com cinco segundos, ponto-timer_light definido com cinco. A luz do tempo agora deve estar acesa. Vamos verificar, timer_light dot is_on, e de fato a luz está acesa. Deveríamos então passar três segundos. Timer_light ponto decorrido (3). A luz ainda deve estar acesa, então vamos verificar novamente. Timer_light dot is_on, é verdadeiro. Vamos passar mais três segundos. Esperamos um anel e a luz apaga-se. Timer_light ponto decorrido, três segundos, esse temporizador está ativo. Esse é o nosso anel, e vamos verificar se a luz está acesa ou não. Ponto Timer_light é_on. Lá vamos nós. Para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Isso conclui nosso treino de luz temporizador. Em seguida, é outro bug misterioso relacionado à herança, que você pode encontrar. Vamos ver o que é esse erro misterioso e como lidar com isso.
17. Mistério (bônus):: Nesta aula, nós vamos explorar o fenômeno chamado Classe Base Frágil. Este estranho causa e como contornar isso. Assim como antes, navegue para responder. it/languages/python3. Então eu sugiro colocar suas janelas Skillshare e responder .it lado a lado, como mostrado aqui. Primeiro, deixe-me apresentar o erro. Vamos definir uma classe A. Dentro desta classe, vamos definir um método hi, que imprime oi, e imprimir oi. Em seguida, definirá um método hello, que também imprime oi. Em seguida, definirá uma classe B, que subclasses A. Em seguida, substituir o método hi para em vez chamar hello. Agora, isso em si não criará problemas. Vamos em frente e ver como usar isso. Vamos acertar “Run” no topo. Então instancie a classe B. Vamos ligar para a B.Hi e sem problemas. Vamos agora criar o problema na classe A. Digamos que percebemos o problema da redundância. Método hi e hello fazer exatamente a mesma coisa, então nós decidimos ter o método hello simplesmente chamar um método hi. Vamos atualizar o método hello para simplesmente chamar oi. Vamos tentar de novo. Vamos acertar a seta verde no topo para executar seu arquivo, então vamos digitar b é igual a B para instanciar, então vamos chamar b.hi e wow. Recebemos esse erro de recursão, profundidade
máxima de recursão excedida. O que aconteceu? Bem, a classe B herda o método “olá “, que chama “oi”. classe B também substitui o método hi para chamar olá, então oi chama olá e olá chamadas oi. Esses dois métodos, oi e hello, continuam chamando um ao outro infinitamente e o erro na parte inferior aqui, profundidade
máxima de recursão excedida, significa que o código foi executado um bajilhão de vezes até que o computador não conseguiu mais lidar com ele. A correção é simples neste caso, simplesmente não redefina Olá para chamar oi. No entanto, em um sistema mais complexo, isso se torna difícil de verificar e aplicar. Infelizmente, no Python, não há nenhuma boa solução integrada para isso. Mas em outras línguas, uma solução é marcar métodos como finais e impossíveis de substituir. Neste caso, poderíamos ter marcado o método hi como final. Para obter uma cópia desses slides e o código concluído para esta lição, certifique-se de conferir o site do curso. Isso conclui o mistério da Classe Base Frágil e sua seção de herança mais. Na verdade, terminamos todos os novos conteúdos para o curso. Na próxima lição, vamos resumir suas atividades,
layouts algumas próximas etapas e descrever o conteúdo bônus. Na próxima lição, vamos resumir seus passos e traçar alguns passos seguintes. Parabéns por ter chegado até aqui. Este não foi um curso fácil e você fez bem.
18. Conclusão: Parabéns por construir sua primeira simulação com programação orientada a objetos. Cobrimos um grande número de conceitos. Conceitos como classes, instâncias, para paradigmas gerais como abstração. Isso é muito material. Mas não se preocupe, você sempre pode reprocurar a sintaxe se você esquecê-la. mais importante, o que você não pode facilmente
procurar é o paradigma de programação orientada a objetos. Como pensar em entidades no mundo ao seu redor como uma série de objetos interagindo uns com os outros. Como usar abstração para legibilidade, herança para manutenção e misturas ou composição para flexibilidade. Se você esquecer esses termos específicos, tudo bem. No entanto, se você se encontrar escrevendo um código
inflexível, insustentável ou ilegível, então pode valer a pena revisitar algumas dessas lições para recuperar a intuição e praticar essas idéias. Sugiro adicionar um novo recurso à sua simulação, talvez adicionar desertos, outros desertos, fazer caminhão de sorvete e, em
seguida, vincular e compartilhar seu projeto na guia projetos e recursos. Mal posso esperar para dar uma olhada. Além disso, agora que você acabou de aprender OOP, você provavelmente tem uma maneira diferente e muito única de explicar seus aspectos deste curso. Se você tem isso em mente, não
hesite em postar na parte de discussão do curso Skillshare. Se isso despertou seu interesse e você está procurando aprender um pouco mais, há alguns próximos passos. Confira os recursos adicionais em alvinwan.com/oop101. Dominar OOP é único e que você não precisa das respostas certas. Em vez disso, basta praticar a concepção de sistemas muito complexos em OOP. Seu momento aha virá quando duas condições forem atendidas. Primeiro, você percebe que seu código é difícil de ler ou difícil de manter. Em segundo lugar, você revisita este curso, aplica essas dicas e percebe como ele torna seu código fácil de dimensionar, fácil de estender ou fácil de ler. Claro, ainda é uma descoberta suave, mas em vez de tentar 100 maneiras diferentes, simplesmente
passei para você a resposta certa que os gênios antes de mim vieram com. Para aprender mais codificação além do OOP, você pode tentar My Computer Vision 101 class para se envolver em visão computacional, MySQL 101 classe para iniciar bancos de dados de design, ou minha classe Data Science 101 para começar a jogar com dados. Eu também projetei este curso para ser auto-suficiente e relativamente curto. Há mais conteúdo chegando para ajudar você a usar entrevistas
de codificação e crescer em um desenvolvedor Python avançado. Se isso parecer interessante, vá para o meu perfil Skillshare e clique em seguir para ser notificado quando a próxima aula for iniciada. Parabéns mais uma vez por fazê-lo no final do curso, e até a próxima vez.