[MÚSICA] Este é o curso de orientação a objetos com Java, meu nome é Eduardo Guerra, e hoje vamos continuar vendo alguns conceitos relacionados a herança e vamos falar sobre a sobrescrita de métodos, que é quando você pega método da superclasse e modifica o comportamento dele na subclasse, e a gente usa isso para especializar o comportamento da subclasse. Vamos ver então como isso funciona nessa aula. Imagina o seguinte: a gente tem ali a classe Empregado, retomando aí o exemplo que a gente estava vendo e ela tem ali o método liquido, que seria para calcular o salário líquido, que ele tem ali, pega o salário, multiplica por 0.85, que aqui no nosso país seria até uma otimismo aí, termos de, que a gente só perde 15% ali com imposto, mas vamos por aí que seria 85% do salário do empregado. O que é que acontece? Como a gente viu na outra aula, o Gerente estende a classe Empregado só que ele tem ali o bônus, então no salário líquido eu tenho que levar consideração o bônus, no caso o bônus, ele não vai incidir, não sei porquê, mas vamos supor aqui que seja uma divisão de lucros e etc que ele tem uma participação e esse imposto não vai incidir sobre este bônus. Então o que é que acontece? Eu posso pegar, criar aquele método liquido na subclasse e redefinir o comportamento dela, então no caso ali eu estou calculando ali o salário vezes 0.85 que é a mesma coisa que tem na superclasse, só que estou somando o bônus, no caso a gente pegou exemplo simples para entender o conceito, mas eu poderia, se fosse cálculo, se fosse uma lógica, eu poderia substituir por uma lógica completamente diferente, então uma classe, ela pode sobrescrever o método da superclasse, como assim sobescrever? É como se ele estivesse escrevendo cima do outro método, esse método liquido que eu estou criando na minha subclasse ele está entrando no lugar daquele método liquido da superclasse, lembra que uma classe quando herda outra ela herda todos os métodos, então se eu não criasse método liquido, ele pegaria esse método liquido da superclasse. Nesse caso, como eu estou criando aqui, ele está entrando no lugar do método liquido. Lembra que eu falei para vocês do contrato, que uma subclasse ela tem que obedecer o contrato, nesse caso, o método liquido, ele é igualzinho para quem está do lado de fora, para quem olha a classe do lado de fora, é a mesma coisa, o que muda é a implementação. Então o contrato é o mesmo só que o comportamento é diferente e essa adaptação de comportamento é crucial, é extremamente importante na orientação a objetos, a modelagem orientada a objetos usa isso muito. Mas eu ainda não estou satisfeito com a implementação, se a gente olhar ali essa parte do salário vezes 0.85 está duplicada, então o que é que vai acontecer? Se eu precisar alterar essa porcentagem, por uma lei que mudou ou por causa de algum estado que tem imposto adicional e etc, eu vou precisar alterar, tanto na superclasse, quanto na subclasse. Eu já vi acontecer sistema que eu trabalhei, a pessoa pegou o método lá da superclasse, duplicou aquele método meio que modificando algumas coisinhas, e aí depois quando alguém precisou alterar uma coisa, modificou só lugar e aí ficou com problema, porquê no outro lugar ainda estava com comportamento antigo, então essa duplicação aí não é interessante. Felizmente, a gente pode utilizar a palavra super, para chamar método que é da superclasse então se eu usar "super.liquido" eu vou estar chamando o método liquido da minha superclasse, e aí então o que é que eu posso fazer? Ao invés de calcular de novo o salário vezes 0.85, eu posso chamar o super ou seja, olha o salário liquido aí do gerente, ele é o salário que a superclasse calcula mais o bônus, então assim se eu precisasse alterar por exemplo essa porcentagem de imposto, eu alteraria só lugar não precisaria estar alterando vários lugares. Pode ter o caso também que você não quer, que ninguém mexa na sua classe, você pode falar assim: olha eu não quero que essa minha classe seja alterada, seja estendida, não quero que ninguém use herança nesta classe, ou mais, você pode falar assim: olha eu tenho essa classe a pessoa pode até usar a herança dessa classe, mas eu não quero que ninguém sobescreva este método específico, porquê ele é essencial aqui para minha classe. Ás vezes por exemplo, eu já vi uma classe que utilizava lá uma thread, para fazer processamento paralelo e tal, e aquilo era inicializado no método daí ele falava: olha nesse método aqui você não mexe, então muitas vezes a gente pode ter essa opção de falar: olha eu criei uma classe aqui mas não é para ninguém estender, ou eu criei método e não é para ninguém sobescrever. Como que a gente faz isso? Existe a palavra chave: final, que você pode estar adiconando classes, métodos e variáveis, e a gente vai ver que para variável é pouquinho diferente. Então, quando a gente coloca o final uma classe, significa que ninguém pode estender ela, significa que você não pode usar herança nessa classe, pegando aí a API básica do Java a gente tem o exemplo da string então a classe string é uma classe final, é uma classe que você não pode estender, então você não pode ir lá e dar: a minha classe extends string, porquê? Porquê ela tem esse modificador final você não pode criar sua string, isso porque a máquina virtual, ela tem todo ali uma forma específica de lidar com a string memória, e ela não quer que ninguém vá lá e mexa e altere o funcionamento disso daí tá? Porque pode dar problema sério na plataforma. Agora se eu utilizar o método modificador final método, nesse caso, eu estou falando que não quero que ninguém sobescreva aquele método, ou seja, as vezes aquele método tem uma funcionalidade extremamente importante que é fixa, que por mais que a pessoa de repente possa estender a classe, aquele método ele não pode mudar. Finalmente, o final variáveis, ele é pouquinho diferente dos outros, ele tem significado diferente, o que é que acontece? Quando eu tenho final, significa que a referência daquela variável não pode mudar, ou seja, eu não posso ir lá e pegar e atribuir outro valor para aquela variável, então se eu criei ali uma variável "e = new Empregado" e ela é final, significa que eu não vou mais poder trocar aquele objeto então, eu não posso fazer "e =" a outro empregado outro objeto da classe empregado, porquê nesse caso eu estaria trocando a referência. Por outro lado, eu posso trabalhar com aquele objeto que está ali, ou seja, eu posso por exemplo ir lá modificar o nome do empregado, eu posso modificar o salário do empregado, então significa que aquela variável ela não pode receber outro objeto, mas eu posso modificar os valores do objeto que está ali dentro. Muita gente ás vezes, se confunde de que o final é uma variável que você não pode modificar, se for uma variável inteira, aí realmente, ou de tipo primitivo, realmente você não pode modificar porque você estaria trocando aquela referência, mas se o final está uma variável que é de tipo de objeto então, você não pode é trocar aquele objeto, mas você pode trocar valores, invocar métodos, dentro daquele objeto que está naquela variável. Espero que com isso vocês tenham entendido como funciona a sobescrita de método e como estar utilizando o final, para gente evitar que essa sobescrita aconteça, vimos também o uso do super, poder estar acessando coisas da superclasse, e estamos cada vez mais entendendo mais aí sobre a parte de herança. Espero que essa parte tenha ficado claro, muito obrigado, até à próxima aula! [MÚSICA]