[MÚSICA] Olá! Bem vindo ao curso de Orientação a Objetos com Java. Eu sou Clovis Fernandes. O objetivo da aula de hoje é falar sobre herança e com dois aspectos: especialização, que olha da classe para a subclasse e generalização, que a gente olha da classe para a superclasse. Então, é isso que nós vamos fazer hoje. Anteriormente, nós vimos os conceitos de generalização e especialização com relação à herança no contexto de diagramas de classes com UML. Agora nós iremos expandir esses conceitos, mostrar com mais detalhes, caracterizá-los e explicá-los com mais detalhes para que vocês possam aplicar quando estiverem fazendo os seus programa Java. A ideia aqui é olhar a herança com esses dois olhares: olhares da especialização e olhares da generalização, mostrando o quanto isso será bom para estruturar melhor o nosso programa. Anteriormente, quando mostramos o diagrama de classe, nós mostramos que o triângulo vazado é que indica essa relação de uma classe com a outra termos de herança que a subclasse herda da superclasse. A superclasse vai transmitir comportamento para a subclasse. A gente usa setas para baixo quando eu estou com esse olhar de especialização e a seta para cima quando nós estamos com esse olhar da generalização. Nós havÃamos mostrado então, também, falado muito rapidamente sobre o princÃpio é-um, que vai olhar da subclasse para a superclasse. Então, quando você diz que uma classe é a superclasse, nesse sentido nós vamos examinar todos os dois conceitos de especialização e generalização. De fato, o conceito é-um, ele é muito importante, porque é ele que vai definir, com mais precisão, se eu vou especializar corretamente ou eu vou generalizar corretamente. Eu sempre vou verificar se faz sentido eu dizer tal classe é uma superclasse, ou tal classe eu posso, então, especializar duas subclasses. Eu tenho que examinar se o conceito é-um vai funcionar ou não. Se não funcionar, não estamos num bom caminho de definir essa hierarquia de herança de classes e superclasses, classes e subclasses. Vamos começar a examinar, para exemplificar, a classe carro. A classe carro, ela tem responsabilidades do tipo "sabe" que são a potência do motor e a velocidade, e tem responsabilidades do tipo "faz" e no nosso exemplo nós estamos mostrando o acelerar e o frear. O quê que acontece? Normalmente, as responsabilidades do tipo "faz", elas vão fazer uso internamente na lógica dessas responsabilidades das responsabilidades do tipo "sabe", então, por exemplo, ao acelerar, eu vou levar conta a potência do motor e vou atingir velocidades à medida que eu vou acelerando. Ao frear, eu vou estar diminuindo a velocidade. Então, como existe essa relação, nós vamos dar uma atenção, quando tratarmos de herança, principalmente ao comportamento. É o que mais nos interessa. Trabalhar com o comportamento. Ou seja, vamos sempre olhar, caso de estarmos trabalhando com herança, com esse olhar do comportamento apenas. É isso que vai nos ajudar a definir hierarquias de classes melhores, que eu possa estar usando depois todo o potencial de polimorfismo e de reuso e de extensão, que essa hierarquia bem estruturada poderá nos proporcionar. Com relação à especialização, vamos começar, então, primeiramente falando sobre a especialização. A seta para baixo, ou seja, eu estou olhando da classe para a subclasse. O quê que acontece? Vamos voltar aos nossos cartões CRC. Eu olho a descrição de cartão e essa descrição do cartão, por exemplo, ela é pouco mais geral e eu tenho na minha aplicação alguma classe que se relaciona com essa descrição, mas ela é pouco mais especÃfica. Então, eu vejo que o relacionamento deles é de herança e que eu tenho uma subclasse que especializa, ela é uma coisa que está restringindo a superclasse. Então, a gente chama isso de especialização. No nosso exemplo aà da classe A, nós temos uma classe A com três métodos: método A1, método A2 e método A3 e uma subclasse B com método B1 e método B2. Vamos expandir a subclasse B exemplificando que nós, de fato, dado que os métodos A1, A2 e A3 são públicos, eu posso herdar esses métodos na subclasse B. O quê que acontece nesse exemplo? O método A1 e o método A2, eles podem ser herdados, vão ser herdados. O quê que acontece? O método A3, numa suposição que estamos fazendo aqui, ele é sobreposto pelo método B2. Embora os nomes aqui estejam diferentes mas, na verdade, é só para exemplificar que é método de B e método de A, mas que eles têm, no fundo, o mesmo nome. Então, ocorreu uma sobreposição. Se eu quiser usar na classe B o método A3, aà eu sou obrigado a colocar super. método A3, que isso indica que eu posso usar na subclasse B esse método que foi sobreposto, senão eu vou ter que usar o método correspondente da classe B, que é o que a gente está exemplificando ali. Com relação à herança com esse olhar da especialização, de cima para baixo, nós temos duas maneiras que nós podemos encarar esse olhar, do que a gente chama de expansão, uma classe como, por exemplo, a classe animal, que você tem, nesse nosso exemplo, 2 responsabilidades, a sua subclasse mamÃfero, que tem mais uma responsabilidade adicional, então, ela herda as duas responsabilidades da classe animal e tem uma classe a mais. Então, há uma expansão, eu passo a ter nesse exemplo, é como se eu tivesse 2 responsabilidades na classe animal e 3 responsabilidades na classe mamÃfero. E depois, eu tenho as classes cão e gato, cada uma com as suas responsabilidades especÃficas. Elas herdam de animal, de mamÃfero e têm a sua responsabilidade especÃfica, então, ela passa a ter 4 responsabilidades. O gato, a mesma coisa, ela passa a ter 4 responsabilidades. Então, é essa expansão que a gente está querendo dizer, é que o número de responsabilidades à medida que eu vou especializando superclasses para subclasses, o número das responsabilidades vão aumentando. Qual a consequência disso? Tem a ver com a outra maneira de a gente olhar, que é com relação à abrangência dos objetos para cada classe, ou seja, essa classe está no topo animal, ela tem uma abrangência maior, ela é mais geral. Eu posso abrigar sobre ela objetos de todo tipo, mamÃferos de todo tipo e não só mamÃferos, outros tipos de animais, né, répteis, aves e insetos, outros tipos de animais eu posso abrigar. Já quando eu uso como mamÃfero, ela é mais restrita do que animal e depois quando eu trabalho com as subclasses, eu estou exemplificando de cão e gato, elas são mais restritas ainda relação a animal porque eu tenho outros tipos de animais carnÃvoros e outros tipos de mamÃferos, né. Eu tenho outros tipos de mamÃferos, eu tenho zebra, eu tenho outros tipos de animais que não são só cão e gato, zebra, elefante e assim por diante, então outros tipos. Então, ele é mais restrito. A gente diz de uma maneira geral que ele é mais especializado. Então, nós temos no topo da hierarquia o significado é mais geral, mais abstrato e na base da hierarquia ele é mais concreto, ele é mais especializado, mais restrito. Agora vamos olhar o relacionamento é-um. Relacionamento é-um, ele é usado para você realmente confirmar se uma dada subclasse realmente faz sentido ser colocada como uma subclasse de uma outra classe. No caso aqui nós temos, por exemplo, pela numeração 1, que gato é mamÃfero. Faz sentido isso? Faz! Gato é mamÃfero. No número 2 mamÃfero, eu estou dizendo que mamÃfero é animal. Faz sentido isso? Também faz. Então, essa hierarquia está, vamos dizer assim, sendo confirmada pelo relacionamento é-um. vale também para o cachorro, cachorro é mamÃfero e mamÃfero é animal, obviamente. O que que tem relação a isso? É o aspecto da transitividade. Como nós estamos vendo pelo número 3, se gato é mamÃfero, mamÃfero é animal, então, gato, faz sentido gato ser animal? Faz, então essa transitividade funciona. Isso vai ser importante porque, se eu faço uma boa hierarquia, nós vamos ter uso muito mais adequado do polimorfismo, que estamos tratando outras aulas. Vocês percebam aqui, que agora eu estou com olhar, da classe para a superclasse, por isso que a gente está usando a seta para cima. Agora vamos falar do outro olhar, até agora estávamos falando da especialização, de cima para baixo, depois começamos a falar do relacionamento, que vai confirmar, se faz sentido essa hierarquia de herança, que era o relacionamento é-um, que é de baixo para cima, está certo? Agora vamos falar sobre a generalização. A especialização, nós vamos criando subclasses, a generalização, nós vamos criando superclasses. Então, ela é o oposto da especialização, a seta é para cima nessa caso, nós estamos olhando da classe para a superclasse. Como é que nós vamos fazer então a generalização? Não é de qualquer jeito, nós vamos voltar aquilo que nós falamos, nós vamos sempre olhar para o comportamento. Então eu vou criar uma classe que faça sentido com relação as descrições das subclasses. Eu vou olhar sempre com base no comportamento e o comportamento eu olho de duas maneiras: vendo a descrição da classe e as suas responsabilidades. Ao criar a superclasse, as classes existentes se tornam subclasses dessa superclasse, além disso, as responsabilidades que são comuns à s classes, elas são transferidas para a superclasse. Então a gente transfere para a superclasse, essas classes que são comuns. Esse processo de generalização, nós vamos exemplificar com duas classes: a Item de Venda e a Item de Compra. Percebam que existem duas responsabilidades que são comuns nas duas classes, as duas responsabilidades comuns são: Atualizar Estoque e Totalizar. Nós devemos olhar mais para saber se podemos fazer a generalização ou não. Então, primeira coisa nós já fizemos, identificamos as responsabilidades comuns, isso é suficiente para fazer a generalização? Não, nós temos que olhar mais duas coisas. Uma, se as descrições são análogas e outra se o relacionamento é-um vai funcionar. Por que, que a gente tem que olhar se as descrições são análogas? Eu posso ter classes que o nome fantasia da responsabilidade é o mesmo, mas as classes não tem nada a ver uma com a outra, então eu não posso generalizar, eu não posso criar uma superclasse com duas coisas diferentes, eu tenho que respeitar as descrições, os tipos, e o comportamento vai ser levado conta relação à isso. No nosso caso aà no exemplo, nós temos Item de Venda e Item de Compra, na descrição de cada uma delas se refere a mercadorias, uma é mercadorias que estão à venda, mercadorias que são compradas, então elas têm muito comum a isso. O que é que eu vou fazer? Vou criar uma superclasse chamada Mercadoria e é isso que eu vou mostrar para vocês. A superclasse Mercadoria está aÃ, o que que eu faço seguida? Transfiro os métodos, as responsabilidades ou métodos que eram comuns da subclasse, para a superclasse, foi o que eu fiz, e confirmo através da verificação do relacionamento é-um. Faz sentido Item de Venda é uma mercadoria? Opa! Faz sentido. Item de Compra, faz sentido, Item de Compra é uma mercadoria? Também faz sentido! Então com isso, essa hierarquia que nós criamos, que nós criamos, que nós generalizamos uma classe com base nas duas classes, está ok, foi bem feito. Resumindo, se eu quero generalizar, ou com cartões CRC ou com classes Java, essas três condições têm que ser respeitadas: eu tenho que ter responsabilidades comuns, mas só isso não é suficiente, as descrições têm que ser análogas, das classes e o relacionamento é-um tem que ser respeitado. Então essas três condições é que devem ser satisfeitas para que eu possa garantir que eu estou fazendo uma hierarquia de classes, de herança saudável, adequada. Na aula de hoje nós completamos, mostramos para vocês que herança pode ser vista de duas maneiras, com esses dois olhares: a especialização, é de cima para baixo, da classe para a subclasse e de baixo para cima, que é a generalização, nós olhamos da classe para a superclasse. E o que amarra tudo isso? É o relacionamento é-um. Obrigado. [MÚSICA]