Herana Polimorfismo e Classes Abstratas em Java Disciplina
Herança, Polimorfismo e Classes Abstratas em Java Disciplina: Programação Orientada a Objetos Prof. Ricardo Satoshi Oyakawa
Herança em Java O que torna a Orientação a Objetos única é o conceito de herança. Herança é um mecanismo que permite que características comuns a diversas classes sejam fatoradas de uma classe base, ou superclasse. A partir de uma classe base, outras classes podem ser especificadas. Cada classe derivada ou subclasse apresenta as características (estrutura e métodos) da superclasse e acrescenta a elas o que for definido de particularidade para ela. 2
Herança em Java Sintaxe: [modificador] class Nome. Da. Superclasse { // corpo da superclasse. . . } [modificador] class Nome. Da. Subclasse extends Nome. Da. Superclasse { // corpo da subclasse. . . } extends - indica que está sendo criada uma nova classe que deriva de uma classe existente Classe existente - superclasse, classe base ou classe progenitora Nova classe - subclasse, classe derivada ou classe filha n Em geral, as subclasses têm mais funcionalidade que sua superclasse. 3
Exemplo de Herança (Superclasse-Empregado. java) import java. text. *; public class Empregado { private String nome; private double salario; public Empregado (String n, double s){ nome = n; salario = s; } public void imprimir (){ System. out. println(nome + " " + formatar. Moeda()); } 4
Exemplo de Herança (Superclasse-Empregado. java) public void aumentar. Salario (double por. Percentual){ salario *= 1 + por. Percentual / 100; } public String formatar. Moeda (){ Number. Format nf = Number. Format. get. Currency. Instance(); nf. set. Minimum. Fraction. Digits (2); String formato. Moeda = String. value. Of(nf. format(salario)); return formato. Moeda; } 5
Exemplo de Herança (Superclasse-Empregado. java) public static void main (String args []){ Empregado [] e = new Empregado [3]; e[0] = new Empregado ("Harry Hacker", 3500); e[1] = new Empregado ("Carl Cracker", 7500); e[2] = new Empregado ("Tony Tester", 3800); int i; for (i = 0; i < 3; i++) e[i]. imprimir(); System. out. println("***************"); for (i = 0; i < 3; i++){ e[i]. aumentar. Salario(10); e[i]. imprimir(); } } } 6
Exemplo de Herança (Subclasse-Gerente. java) import java. text. *; public class Gerente extends Empregado { private String nome. Secretaria; public Gerente (String n, double s){ super (n, s); nome. Secretaria =" "; } public void aumentar. Salario (double por. Percentual){ //adiciona bonus de 20% ao valor do salario double bonus = 20; super. aumentar. Salario(por. Percentual + bonus); } 7
Exemplo de Herança (Subclasse-Gerente. java) public String get. Nome. Secretaria (){ return nome. Secretaria; } public void set. Nome. Secretaria (String nome){ nome. Secretaria = nome; } } 8
Exemplo de Herança Palavra-chave super refere-se a uma superclasse n indica a chamada ao construtor da superclasse n se a superclasse não contiver o construtor padrão e o construtor da subclasse não chamar nenhum outro construtor da superclasse explicitamente compilador java vai informar um erro Em um relacionamento de herança: é necessário apenas indicar as diferenças entre a subclasse e superclasse o reuso é automático n é necessário redefinir métodos um dos 9 primeiros motivos para usar herança n
Exemplo de Herança Exemplo da subclasse Gerente: n redefinição do método aumentar. Salario ( ) n n para que ele funcione diferente para gerentes e empregados comuns esse método não tem acesso direto às variáveis de instância privados da superclasse, ou seja, esse método não pode alterar diretamente a variável de instância salario, embora cada objeto Gerente tenha uma variável de instância salario somente os métodos da classe Empregado têm acesso aos atributos de instância privados Resultado dessa redefinição para objetos da classe Gerente: n Quando se dá a todos os empregados um aumento de 5%, os gerentes vão receber um aumento maior automaticamente 10
Exemplo de Herança (Classe Principal-Gerente. Teste. java) public class Gerente. Teste { public static void main (String args[]){ Gerente g = new Gerente ("Carl Cracker", 7500); g. set. Nome. Secretaria ("Harry Hacker"); Empregado [] e = new Empregado [3]; e[0] = g; e[1] = new Empregado ("Harry Hacker", 3500); e[2] = new Empregado ("Tony Tester", 3800); int i; for (i = 0; i < 3; i++) e[i]. aumentar. Salario(10); for (i = 0; i < 3; i++) e[i]. imprimir(); System. out. println("O nome da secretaria do departamento e: " +g. get. Nome. Secretaria()); } } 11
Subclasses Para saber se a herança é adequada para um programa n n n ter em mente qualquer objeto que seja uma instância de uma subclasse precisa ser utilizável no lugar de um objeto que seja uma instância de superclasse objetos de subclasse são utilizáveis em qualquer código que use a superclasse um objeto de subclasse pode ser passado como argumento para qualquer método que espera um parâmetro de superclasse um objeto de superclasse não pode geralemente ser atribuído a um objeto de subclasse g = e[i]; //erro Os atributos só podem ser adicionados, e não removidos, os objetos de uma subclasse herdados têm, pelo menos, tantos atributos de dados quanto os objetos de superclasse 12
Recomendações de Projeto para Herança 1. 2. 3. Coloque métodos e atributos comuns na superclasse Use herança para modelar uma relação de “estar contido em” (um objeto da subclasse é um (a) objeto da superclasse) Exemplo: classe Empreiteiro Não use herança a menos que todos os métodos herdados façam sentido Exemplo: classe Feriado class Feriado extends Day {. . . } - Um dos métodos públicos da classe Day é avancar. Data ( ), que permite transformar dias feriados em dias normais, de modo que não é um método apropriado para se fazer com dias feriados. Feriado natal; natal. avancar. Data(10); // neste caso, um feriado é um dia 13 mas não um Day (objeto)
Recomendações de Projeto para Herança 4. Use polimorfismo, não informação de tipo - Sempre que você encontrar código do tipo if (x é o tipo 1) acao 1(x); else if (x é o tipo 2) acao 2(x); - Pense em Polimorfismo - acao 1 e acao 2 representam um conceito comum? Caso afirmativo, faça o conceito virar um método de uma superclasse. Assim poderá simplesmente chamar: x. acao( ); - o ponto a ser obervado aqui é que o código para usar métodos polimórficos é muito mais fácil de se manter e estender que um código que use múltiplos testes de tipos de dados. 14
Polimorfismo Comunicação entre objetos: envio de mensagens n ao enviar uma mensagem que pede para uma subclasse aplicar um método usando certos parâmetros n a subclasse verifica se ela tem ou não um método com esse nome e com exatamente os mesmos parâmetros. Se tiver, usa-o. n caso contrário: a superclasse torna-se responsável pelo processamento da mensagem e procura por um método com esse nome e esses parâmetros. Se encontrar, chama esse método. n Uma das regras fundamentais da herança: n um método definido em uma subclasse com o mesmo nome e mesma lista de parâmetros que um método em uma de suas classes antecessoras oculta o método da classe ancestral a partir da 15 subclasse
Polimorfismo Exemplo: n o método aumentar. Salario () da classe Gerente é chamado em vez do método aumentar. Salario () da classe Empregado quando se envia uma mensagem aumentar. Salario ao objeto Gerente Polimorfismo: n n n é a capacidade de um objeto decidir que método aplicar a si mesmo. embora a mensagem possa ser a mesma - os objetos podem responder diferentemente aplicado a qualquer método que seja herdado de uma superclasse 16
Polimorfismo n a chave para fazer polimorfismo: n ligação tardia (late binding) ou ligação dinâmica: n n n o compilador não gera o código para chamar um método em tempo de compilação em vez disso, cada vez que se aplica um método a um objeto, o compilador gera código para calcular que método deve ser chamado, usando informações de tipo do objeto o mecanismo de chamada de método tradicional é chamado ligação estática: determinada em tempo de compilação 17
Classes Abstratas Ao subir na hierarquia de heranças, as classes se tornam mais genéricas e, provavelmente mais abstratas Em algum ponto, a classe ancestral se torna tão geral que acaba sendo vista mais como um modelo para outras classes do que uma classe com instâncias específicas que são usadas Uma classe abstrata não pode ser instanciada, ou seja, não há objetos que possam ser construídos diretamente de sua definição. Classes abstratas correpondem a especificações genéricas, que deverão ser concretizadas em classes derivadas (subclasses). Sintaxe: abstract class Nome. Da. Superclasse { // corpo da classe abstrata. . . } 18
Classes Abstratas Exemplo: n Sistema de mensagens eletrônicas que integre e-mail, fax e correio de voz n Seguindo os princípios OO o programa vai precisar de classes como Mensagem. Texto, Mensagem. Voz e Mensagem. Fax Mensagem. Texto Mensagem. Voz Mensagem. Fax 19
Classes Abstratas Por que se preocupar com um nível tão alto de abstração? n n n Tornar o projeto das classes mais claro Uma das chaves da POO é entender como combinar e reunir operações comuns num nível mais alto na hierarquia de herança Por exemplo: todas as mensagens têm um método comum denominado enviar ( ) n n n é fácil perceber como reproduzir uma mensagem de voz enviando-a ao alto falante, ou uma mensagem de texto exibindo-a em uma janela de texto, ou uma mensagem de fax imprimindo-a ou mostrando-a em uma janela gráfica 20
Classes e Métodos Abstratos Como implementar o método enviar ( ) na superclasse Mensagem? n n A resposta é que não se pode Em Java, usa-se a palavra-chave abstract para indicar que um método não pode ser especificado nessa classe. Para aumentar a clareza, uma classe com um ou mais métodos abstratos precisa, ela mesma, ser declarada abstrata public abstract class Mensagem { … public abstract void enviar ( ); } 21
Classes e Métodos Abstratos n n Além dos métodos abstratos, as classes abstratas podem ter dados e métodos concretos Por exemplo, a classe Mensagem pode armazenar o remetente da mensagem e ter um método concreto que retorne o nome do remetente public abstract class Mensagem { private String remetente; public Mensagem (String r) { remetente = r; } public abstract void enviar ( ); public String get. Remetente( ) { return remetente; } } } 22
Classes e Métodos Abstratos Um método abstrato promete que todos os descendentes não abstratos dessa classe abstrata irão implementar esse método abstrato Os métodos abstratos funcionam como uma espécie de guardador de lugar para métodos que serão posteriormente implementados nas subclasses Uma classe pode ser declarada como abstrata mesmo sem ter métodos abstratos 23
Classes e Métodos Abstratos public class Mensagem. Texto extends Mensagem { private String texto; public Mensagem. Texto(String r, String t) { super (r); texto = t; } public void enviar ( ){ System. out. println(texto); } } - Observe que foi preciso fornecer somente uma definição concreta do método abstrato enviar( ) na classe Mensagem. Texto 24
- Slides: 24