1. Qual Utilidade?
A grande idéia do uso de Herança, é que nos possibilita um Reuso pelo fato de separarmos os elementos (atributos) mais genéricos e abrangentes que costumam ser sempre usados, logo pode-se reaproveitar essa classe para vários diagramas para vários projetos diferentes.A Herança também nos proporciona uma melhoria na Manutenção do nosso código, porque se precisarmos acrescentar ou retirar um atributo genérico que pertence a várias classes, alteraremos apenas em um lugar (Superclasse correspondente).
Segue abaixo um vídeo conceituando bem isso (o vídeo é em inglês).
2. O que é:
Por que será que o processo se chama 'Herança'?Fazendo uma analogia ao que conhecemos, o que é uma herança em nossas vidas? É quando alguém recebe os bens de outra pessoa, geralmente em uma hierarquia familiar.
e O que seria uma 'Herança' em programação? É quando uma classe herda os atributos e comportamentos/métodos (bens) de uma outra classe pré-existente, que pertencem a um mesmo contexto (família), estabelecendo uma relação de 'é um' (a 'Subclasse' é uma 'Superclasse').
2.1 Superclasse e Subclasse
Superclasse é a classe sendo estendida/herdada e Subclasse é a classe que estende/herda os atributos e comportamentos.Superclasse é a base do objeto, que possui atributos e comportamentos comuns em mais do que uma classe, generalizando-as
Subclasse é a classe que vai receber os atributos e comportamentos da Superclasse, além de possuir características próprias, especificando-a.
2.2 Cuidado
A relação de 'é um', serve apenas como um facilitador para nos mostrar a maioria dos processos de herança, no entanto não se deve usá-lo sem entender o propósito da herança, que é herdar seus atributos e comportamentos. Essa relação funciona melhor quando já sabemosque uma classe herda da outra, mas estamos em duvida de quem vai ser a Superclasse e quem vai ser a Subclasse.
Quando se deparar com um código de uma outra pessoa, procure entender para que ele está usando a Herança, pois, nem sempre, somente o nome da classe lhe diz o que ela faz.
Exemplo real: eu posso criar uma classe Veiculo que tenha o método quantidadePneus(){}, e então criar uma Subclasse Carro que vai herdar Veiculo, usando o 'é um' eu posso perguntar "Carro é um Veiculo?", Veiculo por definição do dicionário significa qualquer meio de transporte, carro se enquadra na definição. Então depois de anos com esse sistema funcionando você entra na empresa sem conhecer o código e o dono da empresa resolveu expandir e incluir veículos marítimos e pede para você implementar ao sistema, então você vai criar a classe Navio e repara que já existe uma classe Veiculo, então se pergunta "Navio é um Veiculo?", pelo português sim, porém fazendo isso a sua classe Navio vai herdar o método quantidadePneus(){}, que não faz sentido para um Navio, fazia sentido apenas anteriormente, quando a empresa operava apenas com Carros, e ai o sistema vira uma 'Emilia' completa. Sem contar que pode haver mais de uma definição para a palavra, mesmo no caso da palavra Veiculo possui mais do que uma definição.
Exemplo abstrato: eu tenho uma classe Animal que possui o atributo 'sexo' para definir se o animal é macho ou fêmea. Então criaremos a classe Leão e a classe Minhoca, pela pergunta 'é um' ambos são animais, porém a classe Leão herdando o atributo 'sexo' da classe Animal pode me ajudar a separar os machos das fêmeas e fazer o controle que for preciso, logo o processo de Herança me favorece, no entanto para a classe Minhoca, herdar o atributo 'sexo' não me ajuda, sabendo que todas as minhocas são hermafrodita, mesmo que ela seja um animal, o que a classe Animal possui, não contribui em nada para a classe Minhoca.
Exemplo globalização: suponha que você está encarregado de modificar um código do sistema da sua empresa, mas esse código foi terceirizado e quem fez o código foi alguém que o idioma nativo era algum que possui caracteres totalmente diferentes (Japonês, Chinês, Grego, etc.) e essa pessoa fez o código todo em inglês, porém o nome de algumas classes estavam em seu idioma nativo. Nesse caso não tem como você perguntar se 狼 é um χελώνα.
3. Herança Múltipla
NÃO EXISTE HERANÇA MULTIPLA NO JAVA!!!!
Herança múltipla é quando uma Subclasse herda os atributos e comportamentos de duas ou mais classes. Esse processo é usado para ser possível combinar características de várias Superclasses existentes como um ponto de partida para a criação da sua nova classe.Exemplo: tenho uma classe Carro, que possui os atributos e métodos referentes a quantidade de portas, quantidade de rodas e cor; existe uma outra classe Brinquedo que me diz qual o material do brinquedo. A classe Carro e a classe Brinquedo não possuem relação nenhuma (Carro não é um Brinquedo, Brinquedo não é um Carro).
Agora eu quero criar uma classe CarrinhoBrinquedo, para controlar as especificações de cada carrinho, as portas do carrinho vão ser fixas ou podem abrir/fechar, as rodas serão fixas ou poderão ser trocadas. Essa classe possui tanto as informações genéricas da classe Carro, quanto as informações da classe Brinquedo além de conter características próprias, logo ela herda de ambas as classes.
3.1 Herança Diamante
Esse processo de Herança Múltipla pode gerar um problema, que é chamado de Herança Diamante, que consiste da existência de um polimorfismo em duas ou mais Superclasses de uma mesma Subclasse.Considere a imagem ao lado, nela indicamos que 'A' é uma Superclasse de 'B' e 'C' que são Superclasses de 'D'.
A classe 'A' possui o método teste(), e as classes 'B' e 'C' reimplementam esse método teste(), adequando a cada uma. Agora se criarmos um objeto do tipo 'D' e chamarmos o método teste(); qual versão do método é chamado? a versão definida em 'B' ou em 'C'? exatamente, nem o compilador sabe.
Exemplo: na Linguagem C++ eu posso escrever da seguinte forma D extends B with C -> a implementação de teste() em C vai ser usada ou D extends C with B -> a implementação de teste() em B vai ser usada.
4. No Diagrama de Classes
A Herança no diagrama é representada de
acordo com a imagem abaixo.
A seta 'fechada e branca' está
representando que Funcionario é a Superclasse e Diretor, Professor e
Administrativo são Subclasses de Funcionario.
5. No java
5.1. Criação
Para indicarmos uma Herança, utilizamos o
comando extends indicando quem herda de quem, ou seja, public class
A extends B representa que a classe 'A'
herda o conteúdo da classe 'B'.
5.2 Construtor
O construtor serve para instanciar objetos
de uma classe, ou seja, para que possamos criar dois ou mais objetos com as
mesmas características, mas que não são o mesmo objeto (crio dois objetos de TV,
mas uma tem 15 polegadas e a outra 30 - possuem a mesma característica de
tamanho, porém não são o mesmo objeto).
O construtor é uma função que possui o
mesmo nome da classe, podendo inicializar atributos a partir de parâmetros, não
possui retorno. A classe pode possuir mais do que um construtor, mas deve
conter ao menos um.
sintaxe: public Classe(tipo parametro){}
Exemplo: public Pessoa(String parametroDeNome){}
pode ser feito sem parâmetro ficando public Pessoa(){}.
Na criação do Construtor de uma Subclasse,
precisamos indicar a construção com a Superclasse, para isso utilizamos dentro
da execução do Construtor a sintaxe super();.
Exemplo:
public class
Juridico extends Pessoa{
public
Juridico(){
super();
}
}
5.3 Acesso
Para instanciarmos um objeto usamos Classe objeto = new
Contrutor(); continuando o exemplo acima ficaria Pessoa objPessoa = new Pessoa();
, agora que temos o objeto, para acessarmos os métodos referentes a classe
Pessoa, utilizamos o '.' depois do objeto indicando que estou 'entrando' na
classe para chamar algo, e cada '.' se refere a algo dentro da classe anterior,
ou seja, eu posso acessar da seguinte forma objPessoa.getNome().toUpperCase();
estou dizendo que o objPessoa acessa
a classe Pessoa, chama o método getNome() que retorna uma String que é uma outra classe e que
portanto possui alguns métodos, que no caso está acessando na classe String o método toUpperCase() .
Para controlar o acesso são utilizados os
Modificadores (public, private, protected), na qual public permite que todos
acessem, private somente a classe em que foi declarada e protected podem ser
acessados dentro do pacote ou pelas Subclasses. Se não colocar nada significa
que tem acesso 'default' (também chamado de package private, o modificador
tímido) que só pode ser acessado dentro do pacote em que foi declarado.
Caso seja necessário especificar dentro da Subclasse o que é
referente a ela ou o que é referente a Superclasse, utilizamos o this, para indicar que é referente a
essa classe, e super, para indicar
que é referente a Superclasse (é utilizado quando temos ambigüidade ao código,
ou seja, quando possui o mesmo nome para duas coisas diferentes).
5.4 Curiosidades:
- Uma classe não pode ser Abstract e Final ao mesmo tempo, de modo simples, Abstract existe para ela ser 'estendida' e Final diz que ninguém pode 'estender' essa classe, logo seus princípios são contraditórios, não fazendo sentido ser os dois tipos.
- Você pode criar métodos 'abstract', mas eles só funcionam se a classe for 'abstract' e nas subclasses que também sejam 'abstract', caso a subclasse não seja 'abstract' (sendo concreta) você precisa criar esse mesmo método da Superclasse.
- É possível redefinir a visibilidade/acesso de métodos herdados (private, protected, public), mas sempre empatando ou aumentando a visibilidade, e nunca diminuindo. Sendo private a menor visibilidade (somente a própria classe) e public a maior visibilidade.
- O "tipo de variável" de uma Subclasse servem como parâmetro de um "tipo" da Superclasse, porém só podemos chamar os métodos do tipo escolhido
public class Y extends X (Subclasse de 'X')
Y objeto1 = new Y();
public void metodoQualquer(X parametro){}
Sabendo
que existe meu 'objeto1' do tipo 'Y' e meu 'metodoQualquer' que recebe um parâmetro
do tipo 'X', eu posso executar esse método usando meu 'objeto1' como parametro
-> metodoQualquer(objeto1); No
entanto dentro do método 'metodoQualquer' só podemos utilizar as propriedades
do tipo 'X' que é o que eu garanto que vai existir.
Parte de texto sobre herança
texto1:
Herança
é um mecanismo que permite, a partir de classes com comportamento comum,
abstrair características comuns a todas e centralizá-las em uma classe-base ou
superclasse.
A
partir de uma superclasse, podem ser especificadas outras classes (subclasses),
sendo que uma subclasse pode herdar de (estender) apenas uma superclasse
diretamente. Tal herança consiste em uma subclasse receber as características
(atributos e métodos) da superclasse. No entanto, ela também pode ser acrescida
de outros elementos que não constem de superclasse. Construtores não são
herdados.
É
fundamental compreender como criar objetos a partir de subclasses, como
manipular objetos criados a partir de subclasses e como funcionam as restrições
de acesso aos membros das superclasses.
Apesar
de ser um conceito sofisticado, a herança, na realidade, é usada em todas as
aplicações Java, mesmo que o programador não explicite sua utilização. Isso
ocorre porque, quando se cria uma classe sem qualquer referência a uma
superclasse, o próprio compilador insere na classe criada uma relação de
herança direta com a classe java.lang.Object,
tais como equals() e toString().
A
capacidade de herança garante altos índices de reaproveitamento de código,
permitindo uma melhor componentização.
Retirado do livro:
Entendendo e Dominando o Java - 3a Edição. Editora
Digerati; October 1, 2009. Authors: Oziel Moreira Neto. ISBN - 9788578730888
texto2:
A herança é o
mecanismo de derivação através do qual uma classe pode ser construída como
extensão de outra. Neste processo, todos os atributos e operações da classe
base passam a valer, também, para a classe derivada, podendo esta última
definir novos atributos e operações que atendam suas especificidades.
Uma classe derivada
pode, também, redefinir operações de sua classe base, o que é conhecido como
uma operação de sobrecarga.
O modelo de Orientação
a Objetos coloca grande ênfase nas associações entre classes, pois são
estas que estabelecem os caminhos para navegação, ou troca de mensagens, entre os
objetos que as representam.
Retirado do pdf :
http://neerci.ist.utl.pt/neerci_shelf/LEIC/2%20Ano/1%20Semestre/Programacao%20com%20Objectos/Bibliografia/Programa%E7%E3o%20Orientada%20a%20Objectos.pdf
Vídeos
Roberto Perillo:
XTI aula 47 e 48:
Exercicio de Exemplo
Implemente o diagrama abaixo:
Resolução:
A Herança é feita a partir do 'extends',
criando a possibilidade de quando acessamos um objeto de uma Subclasse nos
mostre o conteúdo de ambas as classes envolvidas.
Exercicio Teorico Praticando
Fixação de conceitos em 3 etapas (Item A, B e C do exercício)
O diagrama da Figura 1.1 fornece um
indicativo da evolução das estrelas (extraído de http://htmlimg4.scribdassets.com/1o21vtrh1c27o6fc/images/1-9a1f1e25d0.png
):
Tendo em vista a Figura 1.1, criar a
hierarquia de classes dada na Figura 1.2:
Item
(A): O método mostrarTipo() deverá mostrar o nome
da classe, o método mostrarDados() deverá retornar o conteúdo de cada um dos
campos (devidamente inicializados por construtores apropriados) e o campo nome
deverá conter o nome do objeto (por exemplo, o nome da estrela do nosso Sistema
Solar é "Sol").
Item
(B): Modificar a classe ProtoEstrela de modo que
seus campos sejam private, bem como
elaborar métodos set e get para modificar e retornar os
valores contidos nos mesmos. Observe que esta modificação faz com que a classe
EstrelaAmarela não tenha mais acesso direto aos campos declarados na classe
ProtoEstrela, sendo, portanto, necessário empregar os métodos set nos
construtores de EstrelaAmarela para inicializar temperatura, magnitude e
luminosidade.
Item
(C): Modificar a classe ProtoEstrela de modo que o
construtor sem parametros use o construtor com parametros por meio da
palavra-chave this. Modificar,
também, a classe EstrelaAmarela de modo que seus construtores empreguem os
construtores da classe ProtoEstrela por meio da palavra-chave super.
Observação
Importante: O uso das palavras-chave this e super irá funcionar independente do modificador de acesso nos
campos da superclasse ser protected
ou private. Isto decorre do fato de
que super chama o construtor da superclasse e este tem total acesso aos campos.
Resolução:
Item (A)
Item (B)
Item (C)
Exercicios Praticos
Referências Bibliográficas
http://ns1.facape.br/jocelio/p3/material_em_pdf/OOHeranca.pdf
http://ccsl.ime.usp.br/files/books/intro-java-cc.pdf
http://www.ruirossi.pro.br/livros/li-rui-pcj-cap14.pdf
DEITEL & DEITEL. Java – como programar. 4a Edição, Bookman, 2003.
FURGERI, SÉRGIO – Java 2 Ensino Didático. Editora Érica, 2002.
SIERRA, KATHY & BATES, BERT. JAVA 2 – Certificação SUN – Programador e
desenvolvedor. 2ª Edição, AltaBooks
DEITEL & DEITEL. Java – como programar. 4a Edição, Bookman, 2003.
FURGERI, SÉRGIO – Java 2 Ensino Didático. Editora Érica, 2002.
SIERRA, KATHY & BATES, BERT. JAVA 2 – Certificação SUN – Programador e
desenvolvedor. 2ª Edição, AltaBooks
Grupo:
Daniel Luz
Gabriel Hiroyuki
Marina Mendez
muito bom!!
ResponderExcluirExcelente Material...parabéns!
ResponderExcluirMuito bom mesmo!!!! Parabéns... apenas o texto poderia estar com alinhamento justificado certo?
ResponderExcluirabçs