Filha

Propaganda
Polimorfismo
Prof. Marcelo Roberto Zorzan
Classe Abstrata ou Interface?
•
Foi desenvolvida uma aplicação Java para registrar as
principais funcionalidades dos instrumentos musicais da
orquestra sinfônica do IFSP-PEP. A orquestra hoje é
formada por uma equipe de 4 músicos, sendo cada um
especializado em um instrumento: guitarra, bateria, baixo e
violão. Para que cada instrumento funcionasse
corretamente foi registrado na aplicação que ele deveria
ser afinado e além disso que fosse possível tocar todas as
notas. Um ano depois da aplicação ter sido concluída foi
solicitado
pela
orquestra
adicionar
uma
nova
funcionalidade ao sistema de limpar o instrumento. Para
este cenário seria melhor usar classe abstrata ou
interface? Por quê?
Classe Abstrata ou Interface?
Uma das vantagens do uso de classes abstratas ao
invés de interfaces é a possibilidade de incluir um novo
método sem quebrar as classes que estão utilizando a
classe abstrata, desde que o método seja concreto.
No caso de interfaces, as classes antigas não estariam
implementando o novo método e portanto não
compilariam mais.
Portanto, uma vez que a interface é liberada e está
sendo usada amplamente, é quase impossível alterá-la,
e por isso é necessário estudar cuidadosamente logo
de início como ela deve ser.
Classe Abstrata ou Interface?
Assim, a regra geral é que uma interface é a melhor
forma de definir um tipo que permite múltiplas
implementações. Uma exceção a essa regra é o caso
em que a facilidade de evolução é considerada mais
importante do que a flexibilidade.
Aula de Hoje
Polimorfismo
O que é polimorfismo?
Polimorfismo significa "várias formas", ou seja, significa
que uma determinada "coisa" pode ser feita de várias
maneiras diferentes.
Uma analogia ao polimorfismo é o sinal dos colégios.
Embora seja um único sinal, ele significa coisas diferentes
para cada aluno:
uns vão para casa,
outros para biblioteca,
outros para o boteco
alguns poucos voltam para sala de aula,
Todos respondem ao sinal, mas cada um do seu jeito.
O que é polimorfismo?
Polimorfismo significa que diferentes tipos de objetos podem
responder a uma mesma mensagem de diferentes maneiras
Classificação Polimorfismo
Inclusão
Em OO, polimorfismo significa que podem existir várias
formas de se fazer chamadas de métodos.
Quem decide "a forma" de fazer é o objeto que recebe a
chamada.
Uma forma mais simples de explicar o conceito de
polimorfismo é dizer que uma variável de uma dada classe
representa não só os objetos dessa classe, mas também
os objetos de todas as suas subclasses
Inclusão
Exemplo:
Empregado
Diretor
Professor
Tecnico
Se um Diretor é um Empregado, o conceito de polimorfismo diz
que uma variável do tipo Empregado pode guardar um objeto do
tipo Diretor. O mesmo vale para Professor e Tecnico
Empregado[] empregados = new Empregado[4];
empregados[0] = new Empregado(”Luis Silva", 10000);
empregados[1] = new Diretor(”Carlos Andrada", 90000, 10);
empregados[2] = new Professor(”João Vale Tudo", 70000, “Auxiliar”);
empregados[3] = new Tecnico(”Pimenta Machado", 50000, 1);
Inclusão
Exemplo:
Empregado
Diretor
Professor
Tecnico
E se a classe Empregado for abstrata?
Empregado[] empregados = new Empregado[4];
empregados[0] = new Empregado(”Luis Silva", 10000); (ERRO!!!)
empregados[1] = new Diretor(”Carlos Andrada", 90000, 10);
empregados[2] = new Professor(”João Vale Tudo", 70000, “Auxiliar”);
empregados[3] = new Tecnico(”Pimenta Machado", 50000, 1);
Inclusão
Para exibir o salário de todos os empregados (diretor,
professor e técnico) bastaria utilizar o seguinte código:
for (int i= 0; i < empregados.length; i++)
empregados[i].exibirSalario();
Inclusão - exemplo
Animal
emitirSom():void
Cachorro
Gato
Pato
emitirSom():void
emitirSom():void
emitirSom():void
Inclusão - exemplo
public abstract class Animal
Animal.java
{
Animal(){}
public abstract void emitirSom();
}
public class Cachorro extends Animal
{
public Cachorro(){}
public void emitirSom()
{
System.out.println("Au, Au!!!");
}
}
Cachorro.java
Inclusão - exemplo
public class Gato extends Animal
{
public Gato(){}
public void emitirSom()
{
System.out.println(“Miau!!!");
}
}
Gato.java
Inclusão - exemplo
public class Pato extends Animal
{
public Pato(){}
public void emitirSom()
{
System.out.println(“Quack!!!");
}
}
Pato.java
Inclusão - exemplo
public class UsandoPolimorfismoComAnimais{
public static void main(String[] args) {
Animal [] animais = new Animal[3];
animais[0] = new Cachorro();
animais[1] = new Gato();
animais[2] = new Pato();
...
UsandoPolimorfismoComAnimais.java
Inclusão - exemplo
...
// Vamos fazer uma brincadeira agora. A gente enfia a mão
// na gaiola (não vale olhar), pega um bicho e aperta o
// pescoço dele pra ver que som sairá.
// Pra fazer isso em Java, a coisa é um pouquinho mais
// chata, a tem que usar um mecanismo pra escolher um
// desses bichos de forma aleatória.
// Vamos então usar um esquema randômico de seleção – a
// classe do Java chamada Randow. Esta parte do código para
// seleção é de pouca importância para o assunto de hoje...
Random seleciona = new Random();
Animal animalEscolhido;
Inclusão - exemplo
...
// Enfiando a mão na gaiola...
for (int i = 0; i < 5; i++)
{
// Pega aleatoriamente um bicho de cada vez da gaiola.
animalEscolhido=gaiolao[seleciona.nextInt(3)];
// Aqui o animal escolhido emitirá o seu som...
// Estamos apertando um pescoço agora...
animalEscolhido.emitirSom();
}
}
}
Inclusão - exemplo
O resultado deste código seria algo como:
Miau!!!
Au, Au!!!
Quack!!!
Coerção
“Downcast”
- Sempre verificado
- Explícito
“Upcast”
- Sempre seguro
- Automático
(aplicação do polimorfismo)
Empregado
Downcast
Upcast
Diretor
Professor
Tecnico
Coerção
Upcast: conversão de um tipo específico para
um tipo mais genérico
Pai
Dado o código: Pai p = new Filha();
p é uma referência da superclasse Pai
apontando para um objeto subclasse Filha
Observe as seguintes instruções:
1.p.m1(); // chama m1( ) da classe Filha
2.p.m2(); // chama m2( ) da classe Pai, herdado por Filha
3.p.m3(); // ERRO de compilação
m1() : void
m2() : void
Filha
m1() : void
m3() : void
Coerção
“Uma referência de superclasse só reconhece membros
disponíveis na superclasse, mesmo que esteja apontando
para um objeto de subclasse.”
A Filha herda do Pai todo o seu conhecimento (atributos
não privados) e comportamentos (métodos), mas pode
acrescentar conhecimento e comportamentos novos
exclusivamente seus, aos quais o Pai não tem acesso.
A parte escura da figura mostra o que o Pai sabe.
Pai
Filha
Coerção
Resumo: upcast é a conversão de um objeto de
tipo mais específico para um tipo mais genérico,
feita implicitamente através de atribuição, mas a
partir da conversão só os membros do tipo mais
genérico podem ser acessados.
Coerção
Downcast: conversão de um tipo genérico para um tipo mais
específico
O relacionamento É UM é sempre da subclasse para a
superclasse. Logo um objeto da classe Pai não é um objeto
da classe Filha.
Pai p = new Filha();
Filha f = p; // Erro
Pode-se "forçar a barra" através de coerção, se soubermos
que o objeto atualmente com referência de superclasse é, na
realidade, um objeto da subclasse para a qual estamos
convertendo.
Coerção
O downcast é realizado utilizando o operador casting de
classes.
1. Pai p = new Filha();
2. Filha f = (Filha) p; //nome da classe destino entre parênteses
3. f.m3();
O código acima será verificado em tempo de execução.
Se o objeto for da subclasse, a coerção será válida, mas se
não for, ocorrerá um erro.
Para proteger o código dessa incerteza deve-se usar o
operador especial instanceof
Coerção
O operador instanceof deve ser usado como segue:
variavelObjeto instanceof NomeClasse
1. Pai p = new Filha();
2. if (p instanceof Filha){
3.
Filha f = (Filha) p;
4.
f.m3();
5. }
Coerção
Exemplo de conversão e seus erros:
Animal
Macaco
Girafa
Animal a; Macaco m; Girafa g;
m = new Macaco();
a = m;
g = (Girafa) m; //Erro em tempo de compilação
g = (Girafa) a; //Erro em tempo de execução
Exercício
Crie uma classe Disciplina que possua como atributos:
nome, período, nota1, nota2 e o método avaliarDisciplina().
•
•
•
Estenda a classe Disciplina, utilizando herança através
das classes DisciplinaTrimestral, DisciplinaSemestral e
DisciplinaAnual.
DisciplinaTrimestral não tem atributos adicionais e calcula o
método avaliarDisciplina() pela fórmula: (nota1 x 0.4) + (nota2 x 0.6).
DisciplinaSemestral tem como atributo adicional nota3 e calcula o
método avaliarDisciplina() pela formula: (nota1 + nota2 + nota3) / 3.0.
DisciplinaAnual possui como atributos adicionais nota3, nota4, nota5
e nota6; e calcula o método avaliarDisciplina() pela fórmula:
((nota1 + nota2 + nota3 + nota4 + nota5) / 5.0 x 0.6) + (nota6 x 0.4).
Exercício
Crie uma aplicação que contenha uma Disciplina Trimestral,
Disciplina Semestral e Disciplina Anual.
Defina um método polimórfico para imprimir o resultado
retornado pelo método avaliarDisciplina().
Download