Herança em Java Curso: Informática Disciplina: Programação Orientada a Objetos Prof. Abrahão Lopes [email protected] Herança - Conceito Quando estudamos biologia aprendemos que herança genética é quando um indivíduo filho recebe características que estão presentes em seus pais, tornando-se “parecido” com seu progenitor, porém podendo apresentar características novas. O mesmo conceito é aplicado à Orientação a Objetos. Herança - Exemplo Digamos que seja necessário criar um sistema para controlar uma coleção de CDs e DVDs. Observe as classes abaixo inicialmente definidas: Herança - Exemplo Observe que existem métodos e atributos que são comuns a ambas as classes. Herança - Exemplo Isso significa que o código que for escrito para a o método setComentario() na classe CD deverá ser repetido na classe DVD. E caso seja necessário realizar alguma alteração, as duas classes precisam ser modificadas. Na classe gerenciadora, será necessário criar duas listas, uma para gerenciar os CDs, outra para gerenciar os DVDs, pois os objetos são diferentes. O mesmo acontece com os métodos adicionar ou excluir. Herança - Exemplo Herança O uso de herança nos ajudará a: Evitar a duplicação de código; Reutilizar o código; Facilitar a manutenção; Estender as funcionalidades da classe; Para usar herança, devemos agrupar todas as características em comum às classes (atributos e métodos) em uma superclasse e colocar as diferenças em subclasses. Herança Para o exemplo do CD e DVD, agrupamos os elementos semelhantes na classe Item e colocamos os detalhes nas classes DVD e CD. Assim, os elementos em comum são descritos apenas uma vez. Herança Dizemos que CD herda da classe Item, o mesmo com a classe DVD. Algumas vezes também ouvimos CD estende Item. O diagrama de herança é representado com setas de ponta vazada. Herança A classe Item (da qual as outras herdam) é chamada classe pai ou superclasse. As classes CD e DVD, que herdam de Item, são chamadas classes filhas ou subclasses. Também podemos nos referir à herança com o termo “é um” como em CD é um Item. Isso é usado para denotar uma especialização da superclasse. Herança Na herança, tudo o que está definido na superclasse também está presente na subclasse. Ou seja, a classe DVD que herda de Item é idêntica a mostrada na figura a direita. = Herança DVD tem tudo o que Item tem e muito mais. A vantagem é que o código só precisará ser implementado uma única vez para qualquer se seja o tipo de item que for adicionado. Exercício 1 Transforme as classes abaixo num modelo de herança. Hierarquias de herança A herança pode ser usada de maneira muito mais geral. Diversas subclasses podem herdar de uma classe, uma subclasse pode herdar de outra subclasse e assim por diante, formando uma hierarquia de heranças. Observe a figura a seguir. Hierarquias de herança Hierarquias de herança Se pegarmos uma instância de Poodle, vamos observar que ele possui algumas características que são comuns a outro tipo de Cão (como latir, farejar, etc.). Veremos também que possui características que nos lembram os mamíferos (ex. pêlos),e outras que nos estão presentes nos animais em geral (dormir, comer, etc.). Isso por que Poodle é um Cão, que é um Mamífero, que é um Animal. Ou seja, Poodle herda de todas essas classes. Exercício 2 Desenhe uma hierarquia de classes para representar as pessoas que fazem parte desta escola (alunos, professores, servidores, calouros, veteranos, mestres, doutores, especialistas, pedagogos, zeladores, porteiros, etc...) Implementando herança em Java Observe os trechos de código abaixo: Para criar uma subclasse, basta adicionar a palavra extends e o nome da superclasse. Exercício 3 Implemente o código Java do Exercício 1. Direitos de Acesso na Herança Atributos e métodos definidos como private na superclasse NÃO PODERÃO SER ACESSADOS pela subclasse. O código ao lado irá gerar um erro de compilação na linha 7, pois DVD está tentando modificar o valor de titulo definido como privado em Item. Direitos de Acesso na Herança Para fazer esta modificação é preciso usar os métodos set da superclasse ou definir os métodos e atributos como protected. Direitos de Acesso na Herança O modificador protected permite que subclasses tenham acesso aos atributos e métodos de sua superclasse como se estivessem definidos nela própria. Inicialização Ao criarmos um objeto, o construtor desse objeto é usado para inicializar os valores de suas variáveis. Nas classes que usam herança precisamos ter um pouco de cuidado ao escrever o código. Nesse exemplo estamos passando dois parâmetros no construtor. Inicialização Ao criar um objeto da subclasse, o construtor deve incorporar o construtor da superclasse, pois não temos acesso direto às variáveis private da superclasse. Ficaria assim: Chamada ao construtor com a palavra super e seus respectivos parâmetros. Inicialização Neste exemplo, o construtor de CD primeiro chama o construtor da classe Item para inicializar suas variáveis, só depois retorna a seu escopo e inicializa suas próprias variáveis. Imagine que um objeto CD fosse como a figura ao lado: (possui um objeto item dentro dele) CD Obj Item ATRIBUTO1; ATRIBUTO2; METODO1( ); METODO2( ); Inicialização No construtor de toda subclasse, a primeira instrução deve ser uma chamada ao construtor da superclasse: super( ). Se você esquecer de colocá-lo, o compilador irá inserir automaticamente essa instrução para garantir a correta inicialização dos atributos da superclasse. Mas só funcionará se o construtor não tiver parâmetros. Adicionando mais elementos Usando a mesma superclasse Item, podemos adicionar outros elementos ao sistema, por exemplo colocando um novo tipo de mídia chamado VideoGame. Adicionando mais elementos Poderíamos ainda modificar a estrutura para representar qualquer tipo de jogo (videogame ou tabuleiro). Adicionando mais elementos As classes Item e Jogo, das quais não temos interesse em criar objetos, ou seja, existem apenas com o propósito de fornecer elementos para herança, são chamadas de classes abstratas. Usamos a palavra abstract antes do nome da classe para defini-la como classe abstrata. Subtipos Uma coisa interessante ao usarmos herança, é que uma variável do tipo da Super classe pode ser usada para referenciar um objeto do tipo de uma subclasse. Chamamos este princípio de Substituição. Veja o exemplo: Item coisa1 = new Item(); CD coisa2 = new CD(); DVD coisa3 = new DVD(); Subtipos Também funcionaria se fosse escrito assim: Item coisa1 = new Item(); Item coisa2 = new CD(); Item coisa3 = new DVD(); Porém o inversão não funciona: CD coisa1 = new Item(); CD coisa2 = new DVD(); //DÁ ERRO! //OUTRO ERRO! Suptipos O uso de subtipos nos permitirá passar objetos de um subtipo em métodos que requerem objetos do tipo da superclasse. Como no exemplo abaixo: Exercício 4 Implemente um sistema quer permita catalogar cds, dvds, jogos de videogames e jogos de tabuleiros (cadastrar e exibir). Use os conceitos de herança aprendidos nesta aula. Referências BARNES. KOLLING. Programação orientada a objetos com Java. Uma introdução prática usando o BlueJ. 4ed. Pearson, 2009. SIERRA, Kathy. BATES, Bert. Use a Cabeça! Java. 2ed. Alta Books, 2007.