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/