(→XP) |
(→XP2020) |
||
(21 intermediate revisions by the same user not shown) | |||
Line 6: | Line 6: | ||
O exemplo implementa vários conceitos, sendo os principais o de cão e o de vigilante. São definidos outros conceitos que especializam estes e outros que fornecem implementações concretas de cada um. Assim, o conceito de robot é o de um vigilante automático e o de cão de guarda um vigilante canino. | O exemplo implementa vários conceitos, sendo os principais o de cão e o de vigilante. São definidos outros conceitos que especializam estes e outros que fornecem implementações concretas de cada um. Assim, o conceito de robot é o de um vigilante automático e o de cão de guarda um vigilante canino. | ||
− | São utilizadas as seguintes interfaces e classes: | + | São utilizadas as seguintes interfaces e classes: '''Cão''', '''Vigilante''', '''CãoDeGuarda''', '''CãoPastor''', '''Chihuahua''', '''Robot''', '''XP''', '''XP2018'''. |
==Cão== | ==Cão== | ||
− | A interface | + | A interface '''Cão''' define as assinaturas dos métodos a que qualquer classe que implemente um cão deve saber responder. |
− | + | <source lang="java"> | |
− | + | interface Cão { | |
− | + | void ladrar(); | |
− | + | int nPatas(); | |
+ | } | ||
+ | </source> | ||
Embora nada seja expresso na interface, além da assinatura, assume-se que a semântica a associar a cada método é a seguinte: | Embora nada seja expresso na interface, além da assinatura, assume-se que a semântica a associar a cada método é a seguinte: | ||
− | * | + | * '''ladrar()''' - executa a acção de produzir um latido |
− | * | + | * '''nPatas()''' - calcula/retorna o número de patas do cão |
− | As classes que implementem a interface, embora não sejam obrigadas a implementar esta semântica, | + | As classes que implementem a interface, embora não sejam obrigadas a implementar esta semântica, têm todo o interesse em fazê-lo. |
==Vigilante== | ==Vigilante== | ||
− | Por seu turno, a interface | + | Por seu turno, a interface '''Vigilante''' define as assinaturas dos métodos a que uma entidade "vigilante" deve saber responder. |
− | + | <source lang="java"> | |
− | + | interface Vigilante { | |
− | + | boolean háIntrusos(); | |
− | + | void soarAlarme(); | |
+ | } | ||
+ | </source> | ||
A semântica a associar pelas implementações é a seguinte: | A semântica a associar pelas implementações é a seguinte: | ||
− | * | + | * '''háIntrusos()''' - retorna '''[[Palavras chave da linguagem Java#true|true]]''' se tiverem sido detectados intrusos |
− | * | + | * '''soarAlarme()''' - executa a acção de activar um alarme, e.g. um sinal sonoro |
==Robot== | ==Robot== | ||
− | A interface | + | A interface '''Robot''' é uma especialização de '''Vigilante''': é um vigilante robotizado que sabe avisar e destruir intrusos. |
− | + | <source lang="java"> | |
− | + | interface Robot extends Vigilante { | |
− | + | void avisarIntrusos(); | |
− | + | void destruirIntrusos(); | |
+ | } | ||
+ | </source> | ||
− | As implementações da interface | + | As implementações da interface '''Robot''', além do que já se disse para a interface '''Vigilante''', devem fornecer a seguinte semântica por método: |
− | * | + | * '''avisarIntrusos()''' -- deve ser emitido um aviso (possivelmente, porque depois se segue a invocação do método '''destruirIntrusos()''' -- mas não há qualquer garantia...) |
− | * | + | * '''destruirIntrusos()''' -- a acção a executar corresponde à destruição dos intrusos |
==Cão de Guarda== | ==Cão de Guarda== | ||
− | A interface | + | A interface '''CãoDeGuarda''', de modo análogo a '''Robot''' define a assinatura das implementações de um cão de guarda, i.e., um cão vigilante. |
− | + | <source lang="java"> | |
− | + | interface CãoDeGuarda extends Cão, Vigilante { | |
− | + | void morder(); | |
+ | } | ||
+ | </source> | ||
− | Note-se a utilização de herança múltipla. | + | Note-se a utilização de herança múltipla relativamente às interfaces. |
==Cão Pastor== | ==Cão Pastor== | ||
− | A primeira classe deste exemplo é | + | A primeira classe deste exemplo é '''CãoPastor'''. Esta classe implementa parte da interface de um cão de guarda e deixa para as suas subclasses a especificidade associada ao método '''ladrar()'''. Embora abstracta, esta classe é uma implementação (ainda que parcial) da interface. |
− | + | <source lang="java"> | |
− | + | public abstract class CãoPastor implements CãoDeGuarda { | |
− | + | public final static int N_PATAS = 4; | |
− | + | ||
− | + | // métodos privados | |
− | + | private void fecharBoca() { /* qualquer coisa */ } | |
− | + | private boolean háPredadores() { | |
− | + | /* qualquer coisa */ | |
− | + | return true; | |
− | + | } | |
− | + | ||
− | + | // interface CãoDeGuarda | |
− | + | public void morder() { fecharBoca(); } | |
− | + | ||
− | + | // inteface Cão | |
− | + | public int nPatas() { return N_PATAS; } | |
− | + | public abstract void ladrar(); | |
− | + | ||
− | + | // interface Vigilante | |
− | + | public void soarAlarme() { ladrar(); } | |
− | + | public boolean háIntrusos() { return háPredadores(); } | |
+ | } | ||
+ | </source> | ||
==Chihuahua== | ==Chihuahua== | ||
− | Um exemplo de uma classe (não abstracta, i.e., implementa | + | Um exemplo de uma classe (não abstracta, i.e., implementa '''ladrar()''') derivada de '''CãoDeGuarda''' é a que se segue. Esta classe apenas necessita de implementar o método '''ladrar()''' para ficar completa. |
− | + | <source lang="java"> | |
− | + | public class Chihuahua extends CãoPastor { | |
− | + | public void ladrar() { System.out.println("guau, guau"); } | |
+ | } | ||
+ | </source> | ||
==XP== | ==XP== | ||
Line 96: | Line 108: | ||
Supõe-se que a classe '''XP''' existe independentemente das outras descritas até aqui (foi, por exemplo, definida para outro fim). Supõe-se, contudo, que contém funcionalidade útil para uma possível implementação de um robot, i.e., para uma classe que implemente a interface '''Robot'''. | Supõe-se que a classe '''XP''' existe independentemente das outras descritas até aqui (foi, por exemplo, definida para outro fim). Supõe-se, contudo, que contém funcionalidade útil para uma possível implementação de um robot, i.e., para uma classe que implemente a interface '''Robot'''. | ||
− | < | + | <source lang="java"> |
public class XP { | public class XP { | ||
public void reboot() { System.out.println("See ya!"); } | public void reboot() { System.out.println("See ya!"); } | ||
Line 103: | Line 115: | ||
public boolean háIntrusos() { return false; } // detector de vírus | public boolean háIntrusos() { return false; } // detector de vírus | ||
} | } | ||
− | </ | + | </source> |
Note-se a coincidência do método '''háIntrusos()''': existe na classe '''XP''' e na interface '''Vigilante''' (da qual '''Robot''' herda parte da sua especificação). É necessário garantir que a semântica pretendida é a que o método realmente fornece. | Note-se a coincidência do método '''háIntrusos()''': existe na classe '''XP''' e na interface '''Vigilante''' (da qual '''Robot''' herda parte da sua especificação). É necessário garantir que a semântica pretendida é a que o método realmente fornece. | ||
Line 109: | Line 121: | ||
==XP2018== | ==XP2018== | ||
− | Esta é uma implementação de | + | Esta é uma implementação de '''Robot''' que reutiliza '''XP'''. |
− | < | + | <source lang="java"> |
public class XP2018 extends XP implements Robot { | public class XP2018 extends XP implements Robot { | ||
// interface Robot | // interface Robot | ||
Line 122: | Line 134: | ||
//public boolean háIntrusos() { return true; } // herdado de XP... | //public boolean háIntrusos() { return true; } // herdado de XP... | ||
} | } | ||
− | </ | + | </source> |
− | Note-se que o método | + | Note-se que o método '''háIntrusos()''' é implementado pela superclasse ('''XP'''). A consideração deste aspecto é de importância crucial, pois pode introduzir erros se o comportamento não for o desejado (o que provavelmente acontece: em '''XP''', os intrusos são -- por hipótese -- virus e em '''XP2018''', uma implementação de um vigilante robotizado, a semântica é outra). |
==Aplicação== | ==Aplicação== | ||
Considere-se a seguinte classe que exercita os conceitos anteriores: | Considere-se a seguinte classe que exercita os conceitos anteriores: | ||
− | < | + | <source lang="java"> |
public class Teste { | public class Teste { | ||
public static void main(String[] args) { | public static void main(String[] args) { | ||
Line 150: | Line 162: | ||
} | } | ||
} | } | ||
− | </ | + | </source> |
==Resultado== | ==Resultado== |
O seguinte exemplo ilustra a utilização de interfaces em Java. Note-se que, além das interfaces, são também utilizadas classes abstractas, por forma a contrastar a utilização de cada conceito. O diagrama UML fornece uma panorâmica do conjunto de interfaces e classes: a amarelo estão representadas as interfaces e a verde as classes abstractas; as classes normais estão a branco.
O exemplo implementa vários conceitos, sendo os principais o de cão e o de vigilante. São definidos outros conceitos que especializam estes e outros que fornecem implementações concretas de cada um. Assim, o conceito de robot é o de um vigilante automático e o de cão de guarda um vigilante canino.
São utilizadas as seguintes interfaces e classes: Cão, Vigilante, CãoDeGuarda, CãoPastor, Chihuahua, Robot, XP, XP2018.
A interface Cão define as assinaturas dos métodos a que qualquer classe que implemente um cão deve saber responder.
interface Cão {
void ladrar();
int nPatas();
}
Embora nada seja expresso na interface, além da assinatura, assume-se que a semântica a associar a cada método é a seguinte:
As classes que implementem a interface, embora não sejam obrigadas a implementar esta semântica, têm todo o interesse em fazê-lo.
Por seu turno, a interface Vigilante define as assinaturas dos métodos a que uma entidade "vigilante" deve saber responder.
interface Vigilante {
boolean háIntrusos();
void soarAlarme();
}
A semântica a associar pelas implementações é a seguinte:
A interface Robot é uma especialização de Vigilante: é um vigilante robotizado que sabe avisar e destruir intrusos.
interface Robot extends Vigilante {
void avisarIntrusos();
void destruirIntrusos();
}
As implementações da interface Robot, além do que já se disse para a interface Vigilante, devem fornecer a seguinte semântica por método:
A interface CãoDeGuarda, de modo análogo a Robot define a assinatura das implementações de um cão de guarda, i.e., um cão vigilante.
interface CãoDeGuarda extends Cão, Vigilante {
void morder();
}
Note-se a utilização de herança múltipla relativamente às interfaces.
A primeira classe deste exemplo é CãoPastor. Esta classe implementa parte da interface de um cão de guarda e deixa para as suas subclasses a especificidade associada ao método ladrar(). Embora abstracta, esta classe é uma implementação (ainda que parcial) da interface.
public abstract class CãoPastor implements CãoDeGuarda {
public final static int N_PATAS = 4;
// métodos privados
private void fecharBoca() { /* qualquer coisa */ }
private boolean háPredadores() {
/* qualquer coisa */
return true;
}
// interface CãoDeGuarda
public void morder() { fecharBoca(); }
// inteface Cão
public int nPatas() { return N_PATAS; }
public abstract void ladrar();
// interface Vigilante
public void soarAlarme() { ladrar(); }
public boolean háIntrusos() { return háPredadores(); }
}
Um exemplo de uma classe (não abstracta, i.e., implementa ladrar()) derivada de CãoDeGuarda é a que se segue. Esta classe apenas necessita de implementar o método ladrar() para ficar completa.
public class Chihuahua extends CãoPastor {
public void ladrar() { System.out.println("guau, guau"); }
}
Supõe-se que a classe XP existe independentemente das outras descritas até aqui (foi, por exemplo, definida para outro fim). Supõe-se, contudo, que contém funcionalidade útil para uma possível implementação de um robot, i.e., para uma classe que implemente a interface Robot.
public class XP {
public void reboot() { System.out.println("See ya!"); }
public void shutdown() { System.out.println("Bye!"); }
public void crash() { System.out.println("Nooo! Argh!!!"); }
public boolean háIntrusos() { return false; } // detector de vírus
}
Note-se a coincidência do método háIntrusos(): existe na classe XP e na interface Vigilante (da qual Robot herda parte da sua especificação). É necessário garantir que a semântica pretendida é a que o método realmente fornece.
Esta é uma implementação de Robot que reutiliza XP.
public class XP2018 extends XP implements Robot {
// interface Robot
public void avisarIntrusos() { System.out.println("Isto é o último aviso!"); }
public void destruirIntrusos() { System.out.println("Eu avisei..."); }
// interface Vigilante
public void soarAlarme() { System.out.println("AAAARGH"); }
//public boolean háIntrusos() { return true; } // herdado de XP...
}
Note-se que o método háIntrusos() é implementado pela superclasse (XP). A consideração deste aspecto é de importância crucial, pois pode introduzir erros se o comportamento não for o desejado (o que provavelmente acontece: em XP, os intrusos são -- por hipótese -- virus e em XP2018, uma implementação de um vigilante robotizado, a semântica é outra).
Considere-se a seguinte classe que exercita os conceitos anteriores:
public class Teste {
public static void main(String[] args) {
Cão c = new Chihuahua();
Vigilante v = new Chihuahua();
CãoPastor p = new Chihuahua();
Robot r = new XP2018();
XP x = new XP();
XP y = new XP2018();
c.ladrar();
v.soarAlarme();
((Chihuahua)v).ladrar();
p.soarAlarme();
r.avisarIntrusos();
r.soarAlarme();
x.reboot();
y.crash();
((XP2018)y).soarAlarme();
}
}
O resultado da aplicação acima é o seguinte:
$ java Teste guau, guau guau, guau guau, guau guau, guau Isto é o último aviso! AAAARGH See ya! Nooo! Argh!!! AAAARGH