Herança, reescrita e polimorfismo - Informática

Propaganda
Desenvolvimento OO com Java
Herança, reescrita e
polimorfismo
Vítor E. Silva Souza
([email protected])
http://www.inf.ufes.br/~vitorsouza
Departamento de Informática
Centro Tecnológico
Universidade Federal do Espírito Santo
Licençaparausoedistribuição
• EsteobraestálicenciadacomumalicençaCreative
Commons Atribuição-CompartilhaIgual 4.0Internacional;
• Vocêtemodireitode:
– Compartilhar:copiareredistribuiromaterialem
qualquersuporteouformato
– Adaptar:remixar,transformar,ecriarapartirdo
materialparaqualquerfim,mesmoquecomercial.
• Deacordocomostermosseguintes:
– Atribuição:vocêdevedarocréditoapropriado,proverumlinkpara
alicençaeindicarsemudançasforamfeitas.Vocêdevefazê-loem
qualquercircunstânciarazoável,masdemaneiraalgumaquesugira
aolicencianteaapoiarvocêouoseuuso;
– CompartilhaIgual:sevocêremixar,transformar,oucriarapartirdo
material,temdedistribuirassuascontribuiçõessobamesma
licençaqueooriginal.
Mais informações podem ser encontradas em:
http://creativecommons.org/licenses/by-sa/4.0/
Abril2016
OO&Java- Herança,reescritaepolimorfismo
2
Conteúdodocurso
• OqueéJava;
• Variáveisprimitivase
controledefluxo;
• Orientaçãoaobjetos
básica;
• Umpoucodevetores;
• Modificadoresdeacesso
eatributosdeclasse;
• Herança,reescritae
polimorfismo;
• Classesabstratas;
• Interfaces;
• Exceçõesecontrolede
erros;
• UtilitáriosdaAPIJava.
EstesslidesforambaseadosnaapostiladocursoFJ-11:Javae
OrientaçãoaObjetosdaCaelum ena apostila Programação
Orientada aObjetos em Javadoprof.Flávio MiguelVarejão.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
3
Reuso/reutilização
• Paraentregarsoftwaredequalidade emmenostempo,
éprecisoreutilizar;
– “Copiar&colar”não éreuso!
• Reusoéumadasprincipaisvantagens anunciadaspela
OrientaçãoaObjetos;
• Mecanismobaseado noconceitodeclasses:
– Composição (“temum”);
– Herança ouderivação(“éum”).
Abril2016
OO&Java- Herança,reescritaepolimorfismo
4
Composição
• Criaçãodeumanova classeusandoclassesexistentes
comoatributos;
• Relacionamento“temum”:umacontatemumtitular
(cliente),umclientetemumnome(string);
• Vimos comofazerissoanteriormente:
– Atributosprimitivos ereferênciasaobjetos;
– Operadoresdeseleção;
– Inicialização (zerareatribuirvalorinicial);
– Ovalornull;
– Atributosestáticos.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
5
Herança
• Criaçãodenovas classesderivando classesexistentes;
• Relacionamento“éum[subtipode]”:umlivroéum
produto,umadministradoréumusuário;
• Usodapalavra-chaveextends;
• Apalavra-chaveésugestiva – aclassequeestásendo
criada“estende”outraclasse:
– Partindo doquejáexiste naquelaclasse...
– Podeadicionar novosrecursos;
– Poderedefinir recursosexistentes.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
6
Motivação
• Classescomelementos (atributos,métodos)repetidos:
class Produto {
String nome;
double preco;
Produto() { } // Precisa?
public Produto(String nome, double preco) {
this.nome = nome; this.preco = preco;
}
public boolean ehCaro() {
return (preco > 100);
}
// Eventuais outros métodos...
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
7
Motivação
• Classescomelementos (atributos,métodos)repetidos:
class Livro {
String nome;
double preco;
String autor;
int paginas;
Não escreva assim, é só
pra caber no slide!
public Livro(String n, double p, String a, int pg) {
nome = n; preco = p; autor = a; paginas = pg;
}
public boolean ehCaro() { return (preco > 100); }
public boolean ehGrande() { return (paginas > 200); }
// Eventuais outros métodos...
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
8
Motivação
• Códigorepetido =problemademanutenção;
– Sesurgeumnovotipodeproduto?
– Semudaalgumacoisaem todos os produtos?
• Colocarosatributosextras emProduto,porémsó
utilizá-los emobjetosquerepresentemlivros?
– Soluçãoconfusa,desperdiçamemória,aindamaisse
ahierarquiacrescer(CDs,DVDs,eletrônicos,etc.);
• Usarcomposição?
– Tambémcausaconfusão.Umlivrotem umproduto
ouumlivroé umproduto?
• SoluçãoOO:herança!
Abril2016
OO&Java- Herança,reescritaepolimorfismo
9
Solução comherança
• Livroestende produto (adiciona novos membros):
class Livro extends Produto {
//private String nome;
// Não preciso repetir.
//private double preco;
// Herdo de Produto
private String autor;
private int paginas;
public Livro(String n, double p, String a, int pg) {
nome = n; preco = p; autor = a; paginas = pg;
}
// Também não preciso repetir:
// public boolean ehCaro() { return (preco > 100); }
public boolean ehGrande() { return (paginas > 200); }
// Eventuais outros métodos...
} Abril2016
OO&Java- Herança,reescritaepolimorfismo
10
Herança em UML
Um livro é um
(tipo de) produto.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
11
Solução comherança
• Podemos chamar métodos doProduto noLivro:
public class Loja {
public static void main(String[] args) {
Livro l = new Livro("Linguagens de Programação",
74.90, "Flávio Varejão", 334);
System.out.println(l.ehCaro());
System.out.println(l.ehGrande());
}
•
•
•
•
Abril2016
Superclasse;
Classebase;
Classepai/mãe;
Classeancestral,etc.
Livro
Produto
}
•
•
•
•
Subclasse;
Classederivada;
Classefilha;
Classedescendente,etc.
OO&Java- Herança,reescritaepolimorfismo
12
Javasuportaherança simples
• Umaclassepodetermuitassubclases;
• Umaclassesó pode ter uma superclasse.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
13
Javanão suporta herança múltipla
Abril2016
OO&Java- Herança,reescritaepolimorfismo
14
Hierarquias dequalquer tamanho
Abril2016
OO&Java- Herança,reescritaepolimorfismo
15
Sintaxe
• Sintaxe:
class Subclasse extends Superclasse {
/* ... */
}
• Semântica:
– Asubclasseherdatodososatributos emétodos que
asuperclassepossuir;
– Subclasseéumaderivação,umsubtipo,uma
extensãodasuperclasse.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
16
Subclassesherdammembros
• Livropossuiautor epaginas (definidosnaprópria
classe);
• Livropossuinome epreco (definidosnasuperclasse);
• LivropoderecebermensagensehGrande() (definida
naprópria classe);
• LivropoderecebermensagensehCaro() (definidana
superclasse).
E se nome e preco fossem
definidos como privativos?
Abril2016
OO&Java- Herança,reescritaepolimorfismo
17
Visibilidade dosatributos herdados
• Acesso privativo é só paraaprópria classe:
class Produto {
private String nome;
private double preco;
// Restante da classe...
}
class Livro extends Produto {
private String autor;
private int paginas;
public Livro(String n, double p, String a, int pg) {
nome = n; preco = p; autor = a; paginas = pg;
}
error: nome has private access in Produto
// Restante da
classe...
nome
= n; preco = p; autor = a; paginas = pg;
^
} Abril2016
OO&Java- Herança,reescritaepolimorfismo
18
Visibilidade dosatributos herdados
• Utilizamos oacesso protegido:
class Produto {
protected String nome;
protected double preco;
// Restante da classe...
}
Atenção! O acesso protegido
não deveria ser usado
automaticamente junto com
a herança. Faz sentido a filha
acessar atributos da mãe?
class Livro extends Produto {
private String autor;
private int paginas;
public Livro(String n, double p, String a, int pg) {
nome = n; preco = p; autor = a; paginas = pg;
}
// Restante da classe...
} Abril2016
OO&Java- Herança,reescritaepolimorfismo
19
Relembrandomodificadoresdeacesso
Acesso
Público
Protegido
Amigo
Privado
A própria classe
Sim
Sim
Sim
Sim
Classe no mesmo
pacote
Sim
Sim
Sim
Não
Subclasse em
pacote diferente
Sim
Sim
Não
Não
Não-subclasse em
pacote diferente
Sim
Não
Não
Não
Abril2016
OO&Java- Herança,reescritaepolimorfismo
20
Reescrita/sobrescrita demétodo
• Ummétodo herdado pode não fazer totalsentido:
preco > 100
preco > 100?
preco > 100?
preco > 100?
Abril2016
OO&Java- Herança,reescritaepolimorfismo
preco > 100?
21
Reescrita/sobrescrita demétodo
• Ummétodo herdado pode não fazer totalsentido:
public class Loja {
public static void main(String[] args) {
Eletronico tv = new Eletronico("TV 40 pol.", 200.0);
// TV 40 pol. por R$ 200? Uma pechincha!
System.out.println(tv.ehCaro()); // true (??)
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
22
Reescrita/sobrescrita demétodo
• Seummétodo herdadonãosatisfaz,podemosredefinilo (reescrevê-lo/sobrescrevê-lo):
class Eletronico extends Produto {
/* Definições anteriores... */
// Eletronicos acima de R$ 1.000,00 são caros!
@Override
public boolean ehCaro() {
return (preco > 1000);
}
}
Que @&#%$ é essa
de @Override?
Abril2016
OO&Java- Herança,reescritaepolimorfismo
23
Anotação @Override
• Palavrasprecedidasde"@"são anotações:
– Meta-dados úteis paraocompilador ou algum outro
componente daplataforma Java;
• @Override indica que ométodo deve sobrescrever um
método herdado;
• Caso contrário (ex.:escrevemos onome dométodo
errado ou esquecemos umparâmetro),gera erro de
compilação.
Quanto mais cedo
detectamos erros, melhor!
Abril2016
OO&Java- Herança,reescritaepolimorfismo
24
Sobrescritavs.sobrecarga
• Cuidado paranãoconfundir:
class Produto {
/* ... */
public void darDesconto(double valor) {
return (preco > 100);
}
}
class Livro extends Produto {
public void darDesconto(int valor) { // Foi feita
return (preco > 100);
// sobregarga,
}
// não sobrescrita!
}
@Override aqui
cairia bem...
Abril2016
OO&Java- Herança,reescritaepolimorfismo
25
Sobrescritavs.sobrecarga
• Cuidado paranãoconfundir:
class Produto {
/* ... */
public void darDesconto(double valor) {
return (preco > 100);
}
}
class Livro extends Produto {
@Override
public void darDesconto(int valor) { // Foi feita
return (preco > 100);
// sobregarga,
}
// não sobrescrita!
}
error: method does not override or
implement a method from a supertype
@Override
^
Abril2016
OO&Java- Herança,reescritaepolimorfismo
26
Entendendoasobrecarga
• Quandotemosváriosmétodoscommesmonome,
dizemosqueestamossobrecarregando aquelenome;
• Éútilparaevitar redundâncias:
– “laveocarro”,“laveacamisa”,“laveocachorro”;
– “laveCarro ocarro”,“laveCamisa acamisa”,
“laveCachorro ocachorro”.
• Fizemosissoquandodefinimos maisdeumconstrutor
paranossaclasse!
• Podemosusar esteconceitoparaqualquer método.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
27
Distinçãoentremétodossobrecarregados
• ComoJavadistingue entredoismétodoscomomesmo
nome?
– Pelostipos dosparâmetros!
– Jávimosquenãopodemosterdois métodoscom
mesmaassinatura,ouseja,mesmonome emesmos
tiposdeparâmetros;
– Aordem dostiposdeparâmetroinflui:
/* OK! */
long multiplicar(long x, int y) { /* ... */ }
long multiplicar(int x, long y) { /* ... */ }
Abril2016
OO&Java- Herança,reescritaepolimorfismo
28
Perigosdasobrecarga
• Devemostercuidado aousarsobrecargaemduas
situações:
– Tiposprimitivos numéricos,quepodemser
convertidos;
– Classesqueparticipamdeumahierarquia com
polimorfismo.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
29
Sobrecargadevalorderetorno?
• Ovalorderetorno deummétodonãoéincluídoemsua
assinatura.Porque?
public class SobreRetorno {
static int retorna10() { return 10; }
static double retorna10() { return 10.0; }
public static void main(String[] args) {
int x = retorna10();
// OK!
double d = retorna10();
// OK!
// Qual método chamar?
System.out.println(retorna10());
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
30
Chamando ométodo original
• Métodossobrescritos podemchamarsuaversão
originalnasuperclasse usandoapalavrasuper:
class Produto {
/* ... */
public void imprimir() {
System.out.println(nome + "," + preco);
}
}
class Livro extends Produto {
/* ... */
public void imprimir() {
super.imprimir();
System.out.println(autor + "," + paginas);
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
31
Chamandooconstrutordasuperclasse
• Possofazeromesmocomconstrutores:
public class Livro extends Produto {
/* ... */
public Livro(String nome, double preco,
String autor, int paginas) {
super(nome, preco);
this.autor = autor;
this.paginas = paginas;
}
}
public class Produto {
/* ... */
public Produto(String nome, double preco) {
this.nome = nome;
this.preco = preco;
É tipo o this(), só
}
que no super()...
} Abril2016
OO&Java- Herança,reescritaepolimorfismo
32
Herança &construção deobjetos
• SeumLivro éumProduto, paracriarmos umlivro
precisamosantescriarumproduto.
class Produto {
String nome;
double preco;
Produto() {
System.out.println("Criando produto sem nome");
} // Precisa?
public Produto(String nome, double preco) {
System.out.println("Criando produto: " + nome);
this.nome = nome; this.preco = preco;
}
// Restante da classe...
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
33
Herança &construção deobjetos
• SeumLivro éumProduto, paracriarmos umlivro
precisamosantescriarumproduto.
class Livro extends Produto {
private String autor;
private int paginas;
public Livro(String n, double p, String a, int pg) {
System.out.println("Criando livro: " + n);
nome = n; preco = p; autor = a; paginas = pg;
}
// Restante da classe...
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
34
Herança &construção deobjetos
• SeumLivro éumProduto, paracriarmos umlivro
precisamosantescriarumproduto.
public class Loja {
public static void main(String[] args) {
Livro l = new Livro("Linguagens de Programação",
74.90, "Flávio Varejão", 334);
// O que vai imprimir?
}
}
Criando produto sem nome
Criando livro: Linguagens de Programação
Abril2016
OO&Java- Herança,reescritaepolimorfismo
35
Herança &construção deobjetos
• Oconstrutor sem argumentos daclasse baseé
chamado implicitamente:
Livro l = new Livro("Linguagens de Programação",
74.90, "Flávio Varejão", 334);
public Livro(String n, double p, String a, int pg) {
// Chamada implícita: super();
System.out.println("Criando livro: " + n);
nome = n; preco = p; autor = a; paginas = pg;
}
Produto() {
System.out.println("Criando produto sem nome");
} // Precisa!!!
Abril2016
OO&Java- Herança,reescritaepolimorfismo
36
Herança &construção deobjetos
• Eseoconstrutorsemargumentosnão existir?
class Produto { /* ... */
public Produto(String nome, double preco) {
this.nome = nome; this.preco = preco;
}
}
class Livro extends Produto { /* ... */
public Livro(String n, double p, String a, int pg) {
nome = n; preco = p; autor = a; paginas = pg;
}
}
error: constructor Produto in class Produto cannot be
applied to given types;
public Livro(String n, double p, String a, int pg) {
^
required: String,double
found: no arguments
reason: actual and OO&Javaformal
argument lists differ in length
Abril2016
Herança,reescritaepolimorfismo
37
Lembre-sedaregra doconstrutor default
class Pessoa {
private String nome;
public Pessoa(String nome) {
this.nome = nome;
}
}
class Aluno extends Pessoa { }
//
//
//
//
//
//
cannot find symbol
symbol : constructor Pessoa()
location: class Pessoa
class Aluno extends Pessoa {
^
1 error
Abril2016
OO&Java- Herança,reescritaepolimorfismo
38
Lembre-sedaregra doconstrutor default
• Aluno nãodefineconstrutor:ganha umdefault;
• Pessoa defineumconstrutorcomparâmetro:não
ganha construtordefault;
• Construtordefaulttenta chamarconstrutorsem
parâmetronasuperclasse(Pessoa);
• Pessoa nãopossuiconstrutorsemparâmetro!
Abril2016
OO&Java- Herança,reescritaepolimorfismo
39
Lembre-sedaregra doconstrutor default
• Asolução échamaroconstrutorexplicitamente;
• Assimcomothis(), super() deveseroprimeiro
comandodoconstrutor.
class Aluno extends Pessoa {
public Aluno() {
super("Sem nome");
}
public Aluno(String nome) {
super(nome);
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
40
Composiçãovs.herança
• Useherança quando:
– Umaclasserepresentaumsubtipo deoutraclasse;
– Construçãodefamílias detipos;
– Usecomcuidado!
• Usecomposição quando:
– Umaclasserepresentaalgoquefazpartedeoutra;
– Prefira composiçãoàherança.
• Osdoisconceitos sãoutilizadosemconjunto atodo
momento!
Abril2016
OO&Java- Herança,reescritaepolimorfismo
41
Composiçãovs.herança
class Lista {
public void adic(int pos, Object obj) { }
public Object obter(int pos) { }
public void remover(int pos) { }
}
// Uma pilha é uma lista?
class Pilha1 extends Lista { }
// Ou uma pilha tem uma lista?
class Pilha2 {
private Lista elementos;
public void empilha(Object obj) { }
public Object desempilha() { }
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
42
Regradebolsodoocultamento
• Demaneirageral:
– Atributos deumaclassedevemserprivados;
– Seaclassepossuifilhas,atributos podemser
protegidos oupossuirmétodos deacesso
protegidos;
– Métodosquepertencemàinterface devemser
públicos;
– Algunsmétodos podemserutilizadosinternamente
e,portanto,seremprivados ouprotegidos.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
43
Vantagensdaherança
• Suportardodesenvolvimentoincremental;
– Classesjátestadas podemserreutilizadas;
– Economiadetempo.
• Relacionamento“éum”:
– Permitesubstituir aclassebaseporumasubclasse
quandoaprimeiraéesperada;
– Propriedadequechamamosdepolimorfismo.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
44
DesenvolvimentoOOcomJava- Herança,reescritaepolimorfismo
APALAVRA-CHAVEFINAL
Abril2016
OO&Java- Herança,reescritaepolimorfismo
45
Apalavrareservadafinal
• Significa“Istonãopodesermudado”;
• Dependendodocontexto,oefeitoélevemente
diferente;
• Podeserusada em:
– Dados (atributos/variáveislocais);
– Métodos;
– Classes.
• Objetivos:
– Eficiência;
– Garantirpropriedades deprojeto.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
46
Dadosfinais
• Constantes sãocomunsemLPs;
– Constantesconhecidas emtempodecompilação
podemadiantar cálculos;
– Constantesinicializadas emtempodeexecução
garantem queovalornãoirámudar.
• EmJava,utiliza-seapalavrafinal:
public static final int MAX = 1000;
private final String NOME = "Java";
final double RAD = Math.PI / 180;
Abril2016
OO&Java- Herança,reescritaepolimorfismo
47
Referênciaconstante
• Umprimitivo constantenuncamudadevalor;
• Umareferência constantenuncamuda,masoobjeto
podemudarinternamente:
public class Teste {
public static final int MAX = 1000;
private final Coordenada C = new Coordenada();
public static void main(String[] args) {
// Erro: MAX = 2000;
// Erro: C = new Coordenada();
C.x = 100; // OK, se x for público!
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
48
Dadosfinaisnãoinicializados
class Viagem { }
class DadoFinalLivre
final int i = 0; //
final int j;
//
final Viagem p; //
{
Final inicializado
Final não inicializado
Referência final não inicializada
// Finais DEVEM ser inicializados em
// todos os construtores e somente neles
DadoFinalLivre () {
j = 1;
p = new Viagem();
}
DadoFinalLivre (int x) {
j = x;
p = new Viagem();
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
49
Argumentosfinais
• Umparâmetro deummétodopodeserfinal:
– Dentrodométodo,funcionacomoconstante.
public class Teste {
public void soImprimir(final int i) {
// Erro: i++;
System.out.println(i);
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
50
Métodosfinais
• Métodosfinaisnão podemsersobrescritos poruma
subclasse;
• Chamadadométodoinline (maioreficiência).
class Telefone {
public final void discar() { }
}
// Não compila: discar() é final!
class TelefoneCelular extends Telefone {
public void discar() { }
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
51
Métodosprivadossãofinais
• Métodosprivados nãopodemseracessados;
• Portanto,sãofinais pornatureza(assubclassesnãotêm
acessoaele).
class Telefone {
private final void checarRede() { }
}
// OK. São dois métodos diferentes!
class TelefoneCelular extends Telefone {
private final void checarRede() { }
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
52
Classesfinais
• Classesfinais nãopodemtersubclasses;
• Porconsequência,todososmétodos deumaclasse
finalsãoautomaticamentefinais.
class Telefone { }
final class TelefoneCelular extends Telefone { }
// Erro: TelefoneCelular é final!
class TelefoneAtomico extends TelefoneCelular { }
Abril2016
OO&Java- Herança,reescritaepolimorfismo
53
DesenvolvimentoOOcomJava- Herança,reescritaepolimorfismo
POLIMORFISMO
Abril2016
OO&Java- Herança,reescritaepolimorfismo
54
Polimorfismo
• Dogregopoli+morphos =múltiplas formas;
• CaracterísticaOOnaqualseadmitetratamento
idêntico paraobjetosdiferentes baseadoemrelações
desemelhança;
• Emoutraspalavras,ondeumaclassebase éesperada,
aceita-sequalquerumadesuassubclasses.
”Enviamos nossos produtos
para todo o Brasil”
Será que envia DVDs
também?
Abril2016
OO&Java- Herança,reescritaepolimorfismo
55
Exemplo:umaplicativodedesenho
Abril2016
OO&Java- Herança,reescritaepolimorfismo
56
Exemplo:umaplicativodedesenho
class Forma {
public void desenhar() {
// A substituir pela implementação oficial...
System.out.println("Forma");
}
}
class Circulo extends Forma {
public void desenhar() {
System.out.println("Círculo");
}
}
class Quadrado extends Forma { /* ... */ }
class Triangulo extends Forma { /* ... */ }
Abril2016
OO&Java- Herança,reescritaepolimorfismo
57
Exemplo:umaplicativodedesenho
• Duasquestões sobre ométodo desenhar():
– Ele temque existir pra todos;
– Eletemquefazer algodiferente paracadaforma!
public class AplicativoDesenho {
private static void desenhar(Forma[] fs) {
for (int i = 0; i < fs.length; i++)
fs[i].desenhar();
}
public static void main(String[] args) {
Forma[] formas = new Forma[] {
new Circulo(), new Forma(),
new Quadrado(), new Triangulo()
};
desenhar(formas);
}
} Abril2016
OO&Java- Herança,reescritaepolimorfismo
58
Ampliação
• Ampliação (upcasting)éaconversãoimplícita deuma
subclasseparaumasuperclasse:
public class AplicativoDesenhoSimples {
public static void desenhar(Forma f) {
f.desenhar();
}
public static void main(String[] args) {
Circulo c = new Circulo();
desenhar(c);
// Upcasting!
Forma f = new Quadrado();
// Upcasting!
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
59
Incrementandooexemplo
• Ocompiladorrealmentenãosabequaléotipo.Veja
umexemplocomgeraçãoaleatória:
public class AplicativoDesenhoAleatorio {
public static void main(String[] args) {
Forma f = null;
switch((int)(Math.random() * 3)) {
case 0: f = new Circulo(); break;
case 1: f = new Quadrado(); break;
case 2: f = new Triangulo(); break;
default: f = new Forma();
}
f.desenhar();
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
60
Esquecendootipodoobjeto
• Quandorealizamosampliação,“esquecemos”otipode
umobjeto:
Forma f = new Quadrado();
• Nãosabemosmaisqualéaclasseespecíficadef.
Sabemosapenas queeleéumaforma;
• Porquefazerisso?
Abril2016
OO&Java- Herança,reescritaepolimorfismo
61
Métodosmaisgerais
• Fazemosampliaçãoparaescrevermosmétodos mais
gerais,parapoupartempoeesforço:
class AplicativoDesenhoTosco {
public static void desenhar(Circulo c) {
c.desenhar();
}
public static void desenhar(Quadrado q) {
q.desenhar();
}
public static void desenhar(Triangulo t) {
t.desenhar();
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
62
Amarração
• Noentanto,setrabalhamoscomForma,comosaber
qualimplementaçãoexecutarquandochamamosum
método?
public class AplicativoDesenho {
private static void desenhar(Forma[] fs) {
for (int i = 0; i < fs.length; i++)
fs[i].desenhar();
}
}
fs[i] é do tipo Forma.
Chamar sempre Forma.desenhar()?
Abril2016
OO&Java- Herança,reescritaepolimorfismo
63
Amarraçãotardia
• Emlinguagensestruturadas,oscompiladoresrealizam
amarraçãoemtempodecompilação;
• EmlinguagensOOcompolimorfismo,nãotemoscomo
saberotiporealdoobjetoemtempodecompilação;
• Aamarraçãoéfeitaemtempodeexecução,também
conhecidacomo:
– Amarraçãotardia;
– Amarraçãodinâmica;ou
– Late binding.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
64
Amarraçãotardia
Abril2016
OO&Java- Herança,reescritaepolimorfismo
65
Quandousar
•
•
•
•
Amarraçãodinâmicaémenoseficiente;
Noentanto,elaquepermiteopolimorfismo;
Javausasempre amarraçãodinâmica;
Aexceção:seummétodoéfinal,Javausaamarração
estática (poiselenãopodesersobrescrito);
• Vocênãopodeescolher quandousarumououtro.É
importanteapenasentender oqueacontece.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
66
Benefíciosdopolimorfismo
• Extensibilidade:
– Podemosadicionarnovas classessemalterar o
métodopolimórfico.
class Retangulo extends Forma {
public void desenhar() {
System.out.println("Retangulo");
}
}
class Quadrado extends Retangulo {
public void desenhar() {
System.out.println("Quadrado");
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
67
Benefíciosdopolimorfismo
class Reta extends Forma {
public void desenhar() {
System.out.println("Reta");
}
}
public class AplicativoDesenhoSimples {
public static void desenhar(Forma f) {
f.desenhar();
}
public static void main(String[] args) {
Forma f = new Reta();
desenhar(f);
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
68
Benefíciosdopolimorfismo
• Ainterface detodosédefinidapelaclassebase;
• Novasclassespossuemamesmainterface,portantoo
sistemajásabelidarcomelas;
• Mesmoquetodasasclassesjáexistamdeprincípio,
poupa-setempo eesforço,codificandoummétodo
único paratodas.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
69
DesenvolvimentoOOcomJava- Herança,reescritaepolimorfismo
ACLASSEOBJECT
Abril2016
OO&Java- Herança,reescritaepolimorfismo
70
AclasseObject
• EmJava,todososobjetos participamdeumamesma
hierarquia,comumaraizúnica;
• Estaraiz éaclassejava.lang.Object.
class Produto { }
/* É equivalente a: */
class Produto extends Object { }
Abril2016
OO&Java- Herança,reescritaepolimorfismo
71
AclasseObject
• Possuialgunsmétodos úteis:
– clone(): criaumacópia doobjeto(usoavançado);
– equals(Object o):verificaseobjetossãoiguais;
– finalize(): chamadopeloGC (nãoégarantia);
– getClass(): retornaaclasse doobjeto;
– hashCode(): funçãohash;
– notify(), notifyAll() ewait():parausocom
threads;
– toString(): converte oobjetoparauma
representaçãocomoString.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
72
OmétodotoString()
• toString() échamadosempreque:
– Tentamosimprimir umobjeto;
– Tentamosconcatená-locomumastring.
public class Loja {
public static void main(String[] args) {
Produto p = new Produto("CD", 30.0);
System.out.println(p);
}
}
// Resultado (toString() herdado de Object):
// Produto@10b62c9
Abril2016
OO&Java- Herança,reescritaepolimorfismo
73
OmétodotoString()
class Produto {
/* ... */
public String toString() {
return nome + " (R$ " + preco + ")";
}
}
public class Loja {
public static void main(String[] args) {
Produto p = new Produto("CD", 30.0);
System.out.println(p);
}
}
// Resultado (toString() sobrescrito):
// CD (R$ 30.0)
Abril2016
OO&Java- Herança,reescritaepolimorfismo
74
OmétodotoString()
• Retornaumarepresentação emString doobjeto em
questão;
• Permitepolimorfismo emgrandeescala:
– Sequisermosimprimir umobjetodequalquer classe,
eleseráchamado;
– Sequisermosconcatenar umobjetodequalquer
classecomumaString, eleseráchamado.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
75
Ométodoequals()
class Valor {
int i;
public Valor(int i) { this.i = i; }
}
public class Teste {
public static void main(String[] args) {
int m = 100;
int n = 100;
System.out.println(m == n);
// true
Valor v = new Valor(100);
Valor u = new Valor(100);
System.out.println(v == u);
// false
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
76
Ométodoequals()
class Valor {
int i;
public Valor(int i) { this.i = i; }
public boolean equals(Object o) {
return (o instanceof Valor)
&& (((Valor)o).i == i);
}
}
public class Teste {
public static void main(String[] args) {
Valor v = new Valor(100);
Valor u = new Valor(100);
System.out.println(v.equals(u));
// true
}
}
Abril2016
OO&Java- Herança,reescritaepolimorfismo
77
Ométodoequals()
• Compara doisobjetos.Retornatrue seforem
iguais/equivalentes,false senão forem;
• Permitempolimorfismo emgrandeescala:
– Podemoscriarumaclasseconjunto quearmazena
objetosdequalquer classe,desdequesejamobjetos
diferentes;
– Podemosimplementarummétodo quepermite
dizerseumobjetoestánoconjunto,seumconjunto
estácontido emoutro,etc.
Abril2016
OO&Java- Herança,reescritaepolimorfismo
78
Exercitaréfundamental
• ApostilaFJ-11daCaelum:
– Seção7.6,página94(discussão sobre herança);
– Seção7.7,página95(contacorrente).
Abril2016
OO&Java- Herança,reescritaepolimorfismo
79
http://nemo.inf.ufes.br/
Download