Classes abstratas e interfaces - Informática

Propaganda
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
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- Classesabstrataseinterfaces
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- Classesabstrataseinterfaces
3
Exemplo:umaplicativodedesenho
Abril2016
OO&Java- Classesabstrataseinterfaces
4
Classesemétodosabstratos
• Classes notopodahierarquiapodemsermuitogerais:
– Oqueéumaforma?
– Como sedesenhaumaforma?
– Como seaumentaumaforma?
• Taisoperaçõesnãofazemsentido.Queremosapenas
definirqueelasexistam,masnãoimplementá-las;
• Asolução:métodosabstratos.
Abril2016
OO&Java- Classesabstrataseinterfaces
5
Classesemétodosabstratos
• Umaclasse quepossuimétodosabstratosdeveser
declaradacomoabstrata:
abstract class Forma {
public abstract void desenhar();
}
class Circulo extends Forma {
@Override
public void desenhar() {
System.out.println("Círculo");
}
}
Abril2016
OO&Java- Classesabstrataseinterfaces
6
Classesabstratas
• Nãopermitemcriaçãodeinstâncias (objetos):
– Ummétodoabstratonãopossuiimplementação,
portantonãopodeserchamado.
• Paraserútil,deveserestendida:
– Suassubclasses devemimplementar ométodoou
declararem-secomoabstratas.
• Servemparadefinirinterfaces eproveralgumas
implementações comuns.
Polimorfismo!
Abril2016
OO&Java- Classesabstrataseinterfaces
7
Construindoahierarquiadeformas
Forma
Decl. desenhar()
Círculo
Triângulo
Retângulo
Retângulo
Decl. desenhar()
Decl. desenhar()
Decl. desenhar()
Impl. desenhar()
Impl. desenhar()
Impl. desenhar()
Quadrado
Quadrado
Decl. desenhar()
Abril2016
OO&Java- Classesabstrataseinterfaces
8
Classesemétodosabstratos- Quiz
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étodo
abstrato?
Sim
Abril2016
OO&Java- Classesabstrataseinterfaces
9
Classesabstratas(puras)econcretas
// 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);
}
Julho2013
DesenvolvimentoOOcomJava
10
Classesabstratas(puras)econcretas
// Classe concreta.
class Retangulo extends Poligono {
public Retangulo() {
super(4);
}
@Override
public void desenhar() {
System.out.println("Retangulo.desenhar");
}
@Override
public void aumentar(int t) {
System.out.println("Retangulo.aumentar");
}
@Override
public void pintar(int cor) {
System.out.println("Retangulo.pintar");
}
}
Julho2013
DesenvolvimentoOOcomJava
11
Interfaces
• Umaclasseabstrata épura quando:
– Possuimétodosabstratos;
– Nãopossuimétodosconcretos;
– Nãopossuiatributos (não-static).
• Javaoferece apalavrareservadainterface:
– Criaumaclasseabstrata pura;
– Chamaremospelonomedeinterface;
– Aoconversarcomoutrosprogramadores,cuidado
paranãoconfundir com“interfacecomousuário”.
Julho2013
DesenvolvimentoOOcomJava
12
Interfaces
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);
}
Julho2013
DesenvolvimentoOOcomJava
13
Interfaces
class Linha implements Forma {
private double x1, y1, x2, y2;
@Override
public void desenhar() {
/* ... */
}
@Override
public void aumentar(int t) {
/* ... */
}
}
Julho2013
DesenvolvimentoOOcomJava
14
Tudoé público na interface
• Métodos definidosnainterfacesãoautomaticamente
Exceção: default methods (Java 8)
públicos eabstratos;
• Atributos definidosnainterfacesãoautomaticamente
públicos eestáticos.
interface Forma {
int x = 10;
void desenhar();
}
Definições
equivalentes
interface Forma {
public static int x = 10;
public abstract void desenhar();
}
Por que isso existe? Só pra
complicar a linguagem?
Julho2013
DesenvolvimentoOOcomJava
15
Porisso,cuidadocomerros
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) {
/* ... */
}
}
Julho2013
DesenvolvimentoOOcomJava
16
Motivação
Texto não é forma, OK!
Como fica o método que
carrega meu desenho do
arquivo que eu salvei no HD?
Abril2016
OO&Java- Classesabstrataseinterfaces
17
Não-solução 1
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…
} Abril2016
OO&Java- Herança,reescritaepolimorfismo
18
Não-solução 2
Já sei!
Abril2016
OO&Java- Classesabstrataseinterfaces
19
Solução:interfaces
Abril2016
OO&Java- Classesabstrataseinterfaces
20
Solução:interfaces
abstract class Forma implements Renderizavel {
/* ... */
@Override
public void renderizar() {
desenhar();
}
}
class Texto implements Renderizavel {
/* ... */
@Override
public void renderizar() {
escrever();
}
}
Julho2013
DesenvolvimentoOOcomJava
21
Solução:interfaces(alternativa)
interface Forma extends Renderizavel {
/* ... */
// As diferentes implementações de forma agora terão
// que implementar renderizar() e não desenhar().
}
class Texto implements Renderizavel {
/* ... */
@Override
public void renderizar() {
escrever();
}
}
Julho2013
DesenvolvimentoOOcomJava
22
Solução:interfaces
public class AplicativoDesenho {
private static void desenhar(Renderizavel[] fs) {
for (int i = 0; i < fs.length; i++)
fs[i].renderizar();
}
}
• Opolimorfismo seamplia:maisummodo de
referenciar umaforma:Renderizavel;
• AplicativoDesenho não precisa saberaclasse realdo
objeto,apenas que ele implementa ainterface;
– Seimplementa ainterface,ele implementa ométodo
renderizar()!
• Novas classes podem ser renderizáveis!
Abril2016
OO&Java- Herança,reescritaepolimorfismo
23
Interface=contrato
• Renderizavel definequetodas asclasses quea
implementamsaibam serenderizar() – “oque”;
– Aimplementação define“ocomo”;
• Defineumcontrato:“quemdesejarserrenderizável
precisasaberserenderizar()”;
– Aclasse quequiser,assina ocontrato ese
responsabilizaacumpri-lo;
• Programevoltadoainterfaces enãoaimplementações
(massemexageros).
Interfaces não são apenas um
cabeçalho .h como em C!
Abril2016
OO&Java- Classesabstrataseinterfaces
24
Herança múltipla em Java
Pode isso,
Arnaldo?
Abril2016
OO&Java- Classesabstrataseinterfaces
25
Herança múltipla em Java
A regra é
clara…
Abril2016
OO&Java- Classesabstrataseinterfaces
26
Herança múltipla em Java
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();
}
}
Julho2013
DesenvolvimentoOOcomJava
27
AinterfaceComparable
• Umexemplo deinterfacenaAPIJavaéainterface
Comparable;
• Defineométodo compareTo(Object obj):
– Compara oobjetoatual(this)comoobjeto
informado(obj);
– Retorna0 sethis =obj;
– Retornaumnúmeronegativosethis <obj;
– Retornaumnúmeropositivosethis >obj.
• Métodosgenéricos autilizamparaordenar coleçõesde
elementos.
Julho2013
DesenvolvimentoOOcomJava
28
AinterfaceComparable
class Valor implements Comparable {
int valor;
public Valor(int v) { valor = v; }
@Override
public int compareTo(Object obj) {
return valor - ((Valor)obj).valor;
}
@Override
public String toString() {
return "" + valor;
}
}
Julho2013
DesenvolvimentoOOcomJava
29
AinterfaceComparable
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;
}
}
Julho2013
DesenvolvimentoOOcomJava
30
DesenvolvimentoOOcomJava– Classesabstrataseinterfaces
OMECANISMODERTTI
Abril2016
OO&Java- Classesabstrataseinterfaces
31
Polimorfismoeextensão
• Compolimorfismo,podemosesquecer aclassedeum
objetoetrabalharcomasuperclasse:
– Ainterface deambaséamesma;
– Aamarraçãodinâmica garantequeométododa
classecorreta seráexecutado.
• Oqueaconteceseasubclasseestende asuperclasse
(adiciona maisfuncionalidade)?
• Seasuperclassenãopossuiaquelafuncionalidade,não
podemoschamá-la!
Julho2013
DesenvolvimentoOOcomJava
32
Polimorfismoeextensão
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!");
}
DesenvolvimentoOOcomJava
} Julho2013
33
Polimorfismoeextensão
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?
Julho2013
DesenvolvimentoOOcomJava
34
Estreitamento(downcast)
• Precisamosrelembrar aclasseespecíficadoobjetopara
chamarmosmétodos quenãoestãonainterfaceda
superclasse;
• Paraissofaremosestreitamento:
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
Julho2013
DesenvolvimentoOOcomJava
35
Upcast vs.downcast
• Ampliaçãoéautomática elivredeerros:
– Aclassebase nãopodepossuirumainterfacemaior
doqueaclassederivada;
– 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
public class Teste {
public static void main(String[] args) {
Animal a = new Cachorro();
Cachorro c = (Cachorro)a;
Upcast
c.latir();
// Forma resumida:
a = new Gato();
((Gato)a).miar();
Downcast
}
}
Julho2013
DesenvolvimentoOOcomJava
37
RTTI:Run-TimeType Identification
• Omecanismoqueverifica otipo deumobjetoem
tempodeexecução chama-seRTTI;
• RTTI=Run-TimeType Identification ouIdentificaçãode
TiposemTempodeExecução;
• Estemecanismogarantequeasconversões sãosempre
seguras;
• Nãopermitequeumobjetosejaconvertido parauma
classeinválida:
– Fora dahierarquia:errodecompilação;
– Dentro dahierarquia:errodeexecução.
Julho2013
DesenvolvimentoOOcomJava
38
RTTI:Run-TimeType Identification
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;
}
}
Julho2013
DesenvolvimentoOOcomJava
39
Ooperadorinstanceof
• OmecanismodeRTTIpermitequevocêconsulte seum
objeto édeumadeterminadaclasse;
• Operadorinstanceof:
– Sintaxe: <objeto> instanceof <Classe>
– Retornatrue seoobjetoforinstância (diretaou
indireta)daclasse especificada;
– Retornafalse casocontrário.
Julho2013
DesenvolvimentoOOcomJava
40
Ooperadorinstanceof
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();
}
}
}
Julho2013
DesenvolvimentoOOcomJava
41
Ousodeinstanceof deveserraro
• Nãoéumaboapráticausarinstanceof:
– Usepolimorfismo;
– Useclassesgenéricas (veremosadiante).
• Useinstanceof apenasquandonãoháoutrasolução.
Julho2013
DesenvolvimentoOOcomJava
42
Trocandoinstanceof porpolimorfismo
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() { /* ... */ }
}
Julho2013
DesenvolvimentoOOcomJava
43
Trocandoinstanceof porgenéricos
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);
}
}
Julho2013
DesenvolvimentoOOcomJava
44
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/
Download