Desenvolvimento OO com Java Classes abstratas e...
Transcript of Desenvolvimento OO com Java Classes abstratas e...
Desenvolvimento OO com Java
Classes abstratas e interfaces
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
CommonsAtribuição-CompartilhaIgual 4.0Internacional;• Vocêtemodireitode:
– Compartilhar:copiareredistribuiromaterialemqualquersuporteouformato
– Adaptar:remixar,transformar,ecriarapartirdomaterialparaqualquerfim,mesmoquecomercial.
• Deacordocomostermosseguintes:– Atribuição:vocêdevedarocréditoapropriado,proverumlinkpara
alicençaeindicarsemudançasforamfeitas.Vocêdevefazê-loemqualquercircunstânciarazoável,masdemaneiraalgumaquesugiraaolicencianteaapoiarvocêouoseuuso;
– CompartilhaIgual:sevocêremixar,transformar,oucriarapartirdomaterial,temdedistribuirassuascontribuiçõessobamesmalicençaqueooriginal.
Abril2016 OO&Java- Classesabstrataseinterfaces 2
Mais informações podem ser encontradas em:http://creativecommons.org/licenses/by-sa/4.0/
Conteúdodocurso
• OqueéJava;• Variáveisprimitivasecontroledefluxo;
• Orientaçãoaobjetosbásica;
• Umpoucodevetores;• Modificadoresdeacessoeatributosdeclasse;
• Herança,reescritaepolimorfismo;
• Classesabstratas;• Interfaces;• Exceçõesecontroledeerros;
• UtilitáriosdaAPIJava.
Abril2016 OO&Java- Classesabstrataseinterfaces 3
EstesslidesforambaseadosnaapostiladocursoFJ-11:JavaeOrientaçãoaObjetosdaCaelum ena apostila ProgramaçãoOrientada aObjetos em Javadoprof.FlávioMiguelVarejão.
Exemplo:umaplicativodedesenho
Abril2016 OO&Java- Classesabstrataseinterfaces 4
Classesemétodosabstratos• Classes notopodahierarquiapodemsermuitogerais:
– Oqueéumaforma?– Como sedesenhaumaforma?– Como seaumentaumaforma?
• Taisoperaçõesnãofazemsentido.Queremosapenasdefinirqueelasexistam,masnãoimplementá-las;
• Asolução:métodosabstratos.
Abril2016 OO&Java- Classesabstrataseinterfaces 5
Classesemétodosabstratos• Umaclasse quepossuimétodosabstratosdeveserdeclaradacomoabstrata:
Abril2016 OO&Java- Classesabstrataseinterfaces 6
abstract class Forma {public abstract void desenhar();
}
class Circulo extends Forma {@Overridepublic void desenhar() {
System.out.println("Círculo");}
}
Classesabstratas• Nãopermitemcriaçãodeinstâncias (objetos):
– Ummétodoabstratonãopossuiimplementação,portantonãopodeserchamado.
• Paraserútil,deveserestendida:– Suassubclasses devemimplementar ométodooudeclararem-secomoabstratas.
• Servemparadefinirinterfaces eproveralgumasimplementações comuns.
Abril2016 OO&Java- Classesabstrataseinterfaces 7
Polimorfismo!
Construindoahierarquiadeformas
Abril2016 OO&Java- Classesabstrataseinterfaces 8
Forma
Círculo Triângulo Retângulo
QuadradoQuadrado
Retângulo
Forma
Decl. desenhar()
Decl. desenhar() Decl. desenhar() Decl. desenhar()
Decl. desenhar()
Impl. desenhar() Impl. desenhar() Impl. desenhar()
Classesemétodosabstratos- Quiz
Abril2016 OO&Java- Classesabstrataseinterfaces 9
Métodos estáticos podem ser abstratos? Não
Construtores podem ser abstratos? Não
Classes abstratas podem ter construtores? Sim
Lembre-se: construtores são chamados pelas subclasses!
Métodos abstratos podem ser privativos? Não
Uma classe abstrata podem estender uma normal? Sim
Posso ter uma classe abstrata sem nenhum métodoabstrato? Sim
Classesabstratas(puras)econcretas
Julho2013 DesenvolvimentoOOcomJava 10
// Classe abstrata pura.abstract class Forma {public abstract void desenhar();public abstract void aumentar(int t);
}
// Classe abstrata.abstract class Poligono extends Forma {private int lados;
public Poligono(int lados) {this.lados = lados;
}
public int getLados() { return lados; }public abstract void pintar(int cor);
}
Classesabstratas(puras)econcretas
Julho2013 DesenvolvimentoOOcomJava 11
// Classe concreta.class Retangulo extends Poligono {public Retangulo() {
super(4);}@Overridepublic void desenhar() {
System.out.println("Retangulo.desenhar");}@Overridepublic void aumentar(int t) {
System.out.println("Retangulo.aumentar");}@Overridepublic void pintar(int cor) {
System.out.println("Retangulo.pintar");}
}
Interfaces• Umaclasseabstrata épura quando:
– Possuimétodosabstratos;– Nãopossuimétodosconcretos;– Nãopossuiatributos (não-static).
• Javaoferece apalavrareservadainterface:– Criaumaclasseabstrata pura;– Chamaremospelonomedeinterface;– Aoconversarcomoutrosprogramadores,cuidadoparanãoconfundir com“interfacecomousuário”.
Julho2013 DesenvolvimentoOOcomJava 12
Interfaces
Julho2013 DesenvolvimentoOOcomJava 13
interface Forma {void desenhar();void aumentar(int t);
}
abstract class Poligono implements Forma {private int lados;
public Poligono(int lados) {this.lados = lados;
}
public int getLados() { return lados; }
public abstract void pintar(int cor);}
Interfaces
Julho2013 DesenvolvimentoOOcomJava 14
class Linha implements Forma {private double x1, y1, x2, y2;
@Overridepublic void desenhar() {
/* ... */}
@Overridepublic void aumentar(int t) {
/* ... */}
}
Tudoé público na interface• Métodos definidosnainterfacesãoautomaticamentepúblicos eabstratos;
• Atributos definidosnainterfacesãoautomaticamentepúblicos eestáticos.
Julho2013 DesenvolvimentoOOcomJava 15
interface Forma {int x = 10;void desenhar();
}
interface Forma {public static int x = 10;public abstract void desenhar();
}
Definições equivalentes
Exceção: default methods (Java 8)
Por que isso existe? Só pracomplicar a linguagem?
Porisso,cuidadocomerros
Julho2013 DesenvolvimentoOOcomJava 16
interface Forma {void desenhar();void aumentar(int t);
}
class Linha implements Forma {// Erro: reduziu de público para privativo ao pacote!void desenhar() {
/* ... */}
// Erro: reduziu de público para privativo!private void aumentar(int t) {
/* ... */ }
}
Motivação
Abril2016 OO&Java- Classesabstrataseinterfaces 17
Texto não é forma, OK!
Como fica o método quecarrega meu desenho do
arquivo que eu salvei no HD?
Não-solução 1
Abril2016 OO&Java- Herança,reescritaepolimorfismo 18
public class AplicativoDesenho {private static void desenhar(Forma[] fs) {
for (int i = 0; i < fs.length; i++)fs[i].desenhar();
}} Texto não é forma! Esse
método não serve…
public class AplicativoDesenho {private static void desenhar(Forma[] fs) {
for (int i = 0; i < fs.length; i++)fs[i].desenhar();
}
private static void desenhar(Texto[] ts) {for (int i = 0; i < ts.length; i++)
ts[i].escrever();}
}Já vimos, com polimorfismo, que essa não é a solução…
Não-solução 2
Abril2016 OO&Java- Classesabstrataseinterfaces 19
Já sei!
Solução:interfaces
Abril2016 OO&Java- Classesabstrataseinterfaces 20
Solução:interfaces
Julho2013 DesenvolvimentoOOcomJava 21
abstract class Forma implements Renderizavel {/* ... */
@Overridepublic void renderizar() {
desenhar();}
}
class Texto implements Renderizavel {/* ... */
@Overridepublic void renderizar() {
escrever();}
}
Solução:interfaces(alternativa)
Julho2013 DesenvolvimentoOOcomJava 22
interface Forma extends Renderizavel {/* ... */
// As diferentes implementações de forma agora terão// que implementar renderizar() e não desenhar().
}
class Texto implements Renderizavel {/* ... */
@Overridepublic void renderizar() {
escrever();}
}
Solução:interfaces
• Opolimorfismo seamplia:maisummodo dereferenciar umaforma:Renderizavel;
• AplicativoDesenho não precisa saberaclasse realdoobjeto,apenas que ele implementa ainterface;– Seimplementa ainterface,ele implementa ométodorenderizar()!
• Novas classes podem ser renderizáveis!Abril2016 OO&Java- Herança,reescritaepolimorfismo 23
public class AplicativoDesenho {private static void desenhar(Renderizavel[] fs) {
for (int i = 0; i < fs.length; i++)fs[i].renderizar();
}}
Interface=contrato• Renderizavel definequetodas asclasses queaimplementamsaibam serenderizar() – “oque”;– Aimplementação define“ocomo”;
• Defineumcontrato:“quemdesejarserrenderizávelprecisasaberserenderizar()”;– Aclasse quequiser,assina ocontrato eseresponsabilizaacumpri-lo;
• Programevoltadoainterfaces enãoaimplementações(massemexageros).
Abril2016 OO&Java- Classesabstrataseinterfaces 24
Interfaces não são apenas um cabeçalho .h como em C!
Herança múltipla em Java
Abril2016 OO&Java- Classesabstrataseinterfaces 25
Pode isso, Arnaldo?
Herança múltipla em Java
Abril2016 OO&Java- Classesabstrataseinterfaces 26
A regra éclara…
Herança múltipla em Java
Julho2013 DesenvolvimentoOOcomJava 27
class CaixaDeTexto extends Texto implements Forma {private Retangulo caixa;
/* ... */
public CaixaDeTexto() {// Parâmetros foram omitidos para simplificar...caixa = new Retangulo();
}
public void renderizar() {// Desenha a caixa.caixa.renderizar();
// Escreve o texto.escrever();
}}
AinterfaceComparable• Umexemplo deinterfacenaAPIJavaéainterfaceComparable;
• Defineométodo compareTo(Object obj):– Compara oobjetoatual(this)comoobjetoinformado(obj);
– Retorna0 sethis =obj;– Retornaumnúmeronegativosethis <obj;– Retornaumnúmeropositivosethis >obj.
• Métodosgenéricos autilizamparaordenar coleçõesdeelementos.
Julho2013 DesenvolvimentoOOcomJava 28
AinterfaceComparable
Julho2013 DesenvolvimentoOOcomJava 29
class Valor implements Comparable {int valor;
public Valor(int v) { valor = v; }
@Overridepublic int compareTo(Object obj) {
return valor - ((Valor)obj).valor;}
@Overridepublic String toString() {
return "" + valor; }
}
AinterfaceComparable
Julho2013 DesenvolvimentoOOcomJava 30
public class Teste {static void imprimir(Object[] vetor) {
for (int i = 0; i < vetor.length; i++)System.out.print(vetor[i] + "; ");
System.out.println();}
public static void main(String[] args) {Valor[] vetor = new Valor[] {
new Valor(10), new Valor(3), new Valor(15), new Valor(7)
};imprimir(vetor); // 10; 3; 15; 7;Arrays.sort(vetor);imprimir(vetor); // 3; 7; 10; 15;
}}
OMECANISMODERTTIDesenvolvimentoOOcomJava– Classesabstrataseinterfaces
Abril2016 OO&Java- Classesabstrataseinterfaces 31
Polimorfismoeextensão• Compolimorfismo,podemosesquecer aclassedeumobjetoetrabalharcomasuperclasse:– Ainterface deambaséamesma;– Aamarraçãodinâmica garantequeométododaclassecorreta seráexecutado.
• Oqueaconteceseasubclasseestende asuperclasse(adiciona maisfuncionalidade)?
• Seasuperclassenãopossuiaquelafuncionalidade,nãopodemoschamá-la!
Julho2013 DesenvolvimentoOOcomJava 32
Polimorfismoeextensão
Julho2013 DesenvolvimentoOOcomJava 33
interface Animal {void comer();
}class Cachorro implements Animal {@Override public void comer() {
System.out.println("Comendo um osso...");}public void latir() {
System.out.println("Au Au!");}
}class Gato implements Animal {@Override public void comer() {
System.out.println("Comendo um peixe...");}public void miar() {
System.out.println("Miau!");}
}
Polimorfismoeextensão
Julho2013 DesenvolvimentoOOcomJava 34
public class Teste {public static void main(String[] args) {
Animal[] vet = new Animal[] {new Cachorro(), new Gato(), new Gato(), new Cachorro()
};
for (int i = 0; i < vet.length; i++) {vet[i].comer();// Erro: vet[i].latir();
}}
} #comofas?
Estreitamento(downcast)• Precisamosrelembrar aclasseespecíficadoobjetoparachamarmosmétodos quenãoestãonainterfacedasuperclasse;
• Paraissofaremosestreitamento:
Julho2013 DesenvolvimentoOOcomJava 35
Ampliação (upcast) Estreitamento (downcast)
int para long long para int
float para double double para float
Cachorro para Animal Animal para Cachorro
Gato para Animal Animal para Gato
Upcast vs.downcast• Ampliaçãoéautomática elivredeerros:
– Aclassebase nãopodepossuirumainterfacemaiordoqueaclassederivada;
– Nãoénecessárioexplicitar oupcast.• Estreitamentoémanual epodecausarerros:
– Aclassebasepodetervárias subclassesevocêestáconvertendoparaaclasseerrada;
– Énecessárioexplicitar odowncast;– Podelançarumerro (ClassCastException);– Podehaverperda deinformação(tiposprimitivos).
Julho2013 DesenvolvimentoOOcomJava 36
Upcast vs.downcast
Julho2013 DesenvolvimentoOOcomJava 37
public class Teste {public static void main(String[] args) {
Animal a = new Cachorro();Cachorro c = (Cachorro)a;c.latir();
// Forma resumida:a = new Gato();((Gato)a).miar();
}}
Upcast
Downcast
RTTI:Run-TimeType Identification• Omecanismoqueverifica otipo deumobjetoemtempodeexecução chama-seRTTI;
• RTTI=Run-TimeType Identification ouIdentificaçãodeTiposemTempodeExecução;
• Estemecanismogarantequeasconversões sãosempreseguras;
• Nãopermitequeumobjetosejaconvertido paraumaclasseinválida:– Fora dahierarquia:errodecompilação;– Dentro dahierarquia:errodeexecução.
Julho2013 DesenvolvimentoOOcomJava 38
RTTI:Run-TimeType Identification
Julho2013 DesenvolvimentoOOcomJava 39
public class Teste {public static void main(String[] args) {
Animal a = new Cachorro();
// Sem erro nenhum:Cachorro c = (Cachorro)a;
// Erro de execução (ClassCastException):Gato g = (Gato)a;
// Erro de compilação:String s = (String)a;
}}
Ooperadorinstanceof• OmecanismodeRTTIpermitequevocêconsulte seumobjeto édeumadeterminadaclasse;
• Operadorinstanceof:– Sintaxe:<objeto> instanceof <Classe>
– Retornatrue seoobjetoforinstância (diretaouindireta)daclasse especificada;
– Retornafalse casocontrário.
Julho2013 DesenvolvimentoOOcomJava 40
Ooperadorinstanceof
Julho2013 DesenvolvimentoOOcomJava 41
public class Teste {public static void main(String[] args) {
Animal[] vet = new Animal[] {new Cachorro(), new Gato(), new Gato(), new Cachorro()
};
for (int i = 0; i < vet.length; i++) {if (vet[i] instanceof Cachorro)
((Cachorro)vet[i]).latir();else if (vet[i] instanceof Gato)
((Gato)vet[i]).miar();}
}}
Ousodeinstanceof deveserraro• Nãoéumaboapráticausarinstanceof:
– Usepolimorfismo;– Useclassesgenéricas (veremosadiante).
• Useinstanceof apenasquandonãoháoutrasolução.
Julho2013 DesenvolvimentoOOcomJava 42
Trocandoinstanceof porpolimorfismo
Julho2013 DesenvolvimentoOOcomJava 43
interface Animal {void comer();void falar();
}
class Cachorro extends Animal {@Override public void comer() { /* ... */ }@Override public void falar() { /* ... */ }
}
class Gato extends Animal {@Override public void comer() { /* ... */ }@Override public void falar() { /* ... */ }
}
Trocandoinstanceof porgenéricos
Julho2013 DesenvolvimentoOOcomJava 44
public class Teste {public static void main(String[] args) {
Cachorro c;
List lista = new ArrayList();lista.add(new Cachorro());Object o = lista.get(0);if (o instanceof Cachorro) c = (Cachorro)o;
// Com genéricos.List<Cachorro> listaGen; listaGen = new ArrayList<Cachorro>();listaGen.add(new Cachorro());c = listaGen.get(0);
}}
Exercitaréfundamental• ApostilaFJ-11daCaelum – ClassesAbstratas:
– Seção9.6,página121(conta corrente);– Seção9.7,página123(desafios);
• ApostilaFJ-11daCaelum – Interfaces:– Seção 10.5,página 134(formas,conta corrente);– Seção 10.6,página 138(exercícios avançados);– Seção 10.7,página 139(discussão).
Abril2016 OO&Java- Classesabstrataseinterfaces 45
http://nemo.inf.ufes.br/