 |
 |
8) Interfaces et classes internes |
|
 |
|
Texte original |
 |
Traducteur : Jérome QUELIN |
|
 |
|
Ce chapitre contient 6 pages
1
2
3
4
5
6
|
|
|
 |
 |
 |
 |
 |
 |
|
 |
05.07.01 - version 5.4 [Armel] : - Ajout des tags de sépartions de pages pour le site. 25.04.2001 - version 5.3 : - Mise en forme du code html (titres-hx[verdana], paragraphes-p[Georgia], code-blockquote). 14.07.2000 - version 5.2 : - Corrections apportées par Jean-Pierre Vidal. 08.07.2000 - version 5.1 : - Première publication sur eGroups. Traducteur : - Jérome QUELIN Texte original : -Thinking in Java, 2nd edition, Revision 10 © 2000 by Bruce Eckel
|
 |
 |
 |
8: Interfaces & Inner Classes
|
 |
8 : Interfaces & Classes Internes
|
 |
 |
 |
Interfaces and inner classes
provide more sophisticated ways to organize and control the objects in your
system.
|
 |
Les interfaces et les classes internes sont des manières plus
sophistiquées d'organiser et de contrôler les objets du système construit.
|
 |
 |
 |
C++, for example, does not contain such
mechanisms, although the clever programmer may simulate them. The fact that they
exist in Java indicates that they were considered important enough to provide
direct support through language keywords.
|
 |
C++, par exemple, ne propose pas ces mécanismes, bien que le programmeur
expérimenté puisse les simuler. Le fait qu'ils soient présents dans Java indique qu'ils furent
considérés comme assez importants pour être intégrés directement grâce à des mots-clefs.
|
 |
 |
 |
In Chapter 7, you learned about the
abstract keyword, which allows you to create one or more methods in a
class that have no definitions—you provide part of the interface without
providing a corresponding implementation, which is created by inheritors. The
interface keyword produces a completely abstract class, one that provides
no implementation at all. You’ll learn that the interface is more
than just an abstract class taken to the extreme, since it allows you to perform
a variation on C++’s “multiple inheritance,” by creating a
class that can be upcast to more than one base type.
|
 |
Dans le chapitre 7, on a vu le mot-clef abstract, qui
permet de créer une ou plusieurs méthodes dans une classe qui n'ont pas de définition - on fournit
une partie de l'interface sans l'implémentation correspondante, qui est créée par ses héritiers. Le
mot-clef interface produit une classe complètement abstraite, qui ne fournit
absolument aucune implémentation. Nous verrons qu'une interface est un peu plus
qu'une classe abstraite poussée à l'extrême, puisqu'elle permet d'implémenter « l'héritage
multiple » du C++ en créant une classe qui peut être transtypée en plus d'un type de
base.
|
 |
 |
 |
At first, inner classes look like a
simple code-hiding mechanism: you place classes inside other classes.
You’ll learn, however, that the inner class does more than that—it
knows about and can communicate with the surrounding class—and that the
kind of code you can write with inner classes is more elegant and clear,
although it is a new concept to most. It takes some time to become comfortable
with design using inner classes.
|
 |
Les classes internes ressemblent au premier abord à un simple mécanisme de
dissimulation de code : on crée une classe à l'intérieur d'autres classes. Cependant, les classes
internes font plus que cela - elles connaissent et peuvent communiquer avec la classe principale -
; sans compter que le code produit en utilisant les classes internes est plus élégant et
compréhensible, bien que ce soit un concept nouveau pour beaucoup. Cela prend un certain temps
avant d'intégrer les classes internes dans la conception.
|
 |
 |
 |
Interfaces
|
 |
Interfaces
|
 |
 |
 |
The
interface keyword takes the abstract
concept one step further. You could think of it as a “pure”
abstract class. It allows the creator to establish the form for a class:
method names, argument lists, and return types, but no method bodies. An
interface can also contain fields, but these are implicitly
static and final. An
interface provides only a form, but no
implementation.
|
 |
Le mot-clef interface pousse le concept
abstract un cran plus loin. On peut y penser comme à une classe
« purement » abstract. Il permet au créateur d'établir la forme qu'aura
la classe : les noms des méthodes, les listes d'arguments et les types de retour, mais pas les
corps des méthodes. Une interface peut aussi contenir des données membres, mais
elles seront implicitement static et final. Une
interface fournit un patron pour la classe, mais aucune implémentation.
|
 |
 |
 |
An interface says: “This is
what all classes that implement this particular interface will look
like.” Thus, any code that uses a particular interface knows what
methods might be called for that interface, and that’s all. So the
interface is used to establish a “protocol” between classes.
(Some object-oriented programming languages have a keyword called
protocol to do the same
thing.)
|
 |
Une interface déclare : « Voici ce à quoi ressemblera
toutes les classes qui implémenteront cette interface ». Ainsi, tout code utilisant
une interface particulière sait quelles méthodes peuvent être appelées pour cette
interface, et c'est tout. Une interface est donc utilisée pour
établir un « protocole » entre les classes (certains langages de programmation orientés
objets ont un mot-clef protocol pour réaliser la même chose).
|
 |
 |
 |
To create an interface, use the
interface keyword instead of the class keyword. Like a class, you
can add the public keyword before the interface
keyword (but only if that interface is defined in a file of the same
name) or leave it off to give “friendly”
status so that it is only usable within the same package.
|
 |
Pour créer une interface, il faut utiliser le
mot-clef interface à la place du mot-clef class. Comme pour une
classe, on peut ajouter le mot-clef public devant le mot-clef
interface (mais seulement si l'interface est définie dans un
fichier du même nom) ou ne rien mettre pour lui donner le statut « amical » afin qu'elle
ne soit utilisable que dans le même package.
|
 |
 |
 |
To make a class that conforms to a
particular interface (or group of interfaces) use the
implements keyword. You’re saying “The
interface is what it looks like but now I’m going to say how it
works.” Other than that, it looks like inheritance. The diagram for
the instrument example shows this:
|
 |
Le mot-clef implements permet de rendre une classe
conforme à une interface particulière (ou à un groupe
d'interfaces). Il dit en gros : « L'interface spécifie ce à
quoi la classe ressemble, mais maintenant on va spécifier comment cela fonctionne ».
Sinon, cela s'apparente à de l'héritage. Le diagramme des instruments de musique suivant le montre
:
|
 |
 |
 |
|
 |
|
 |
 |
 |
Once you’ve implemented an
interface, that implementation becomes an ordinary class that can be
extended in the regular way.
|
 |
Une fois une interface implémentée, cette implémentation
devient une classe ordinaire qui peut être étendue d'une façon tout à fait classique.
|
 |
 |
 |
You can choose to explicitly declare the
method declarations in an interface as public. But they are
public even if you don’t say it. So when you implement an
interface, the methods from the interface must be defined as
public. Otherwise they would default to “friendly,” and
you’d be reducing the accessibility of a method during inheritance, which
is not allowed by the Java compiler.
|
 |
On peut choisir de déclarer explicitement les méthodes d'une
interface comme public. Mais elles sont public
même sans le préciser. C'est pourquoi il faut définir les méthodes d'une
interface comme public quand on implémente une
interface. Autrement elles sont « amicales » par défaut, impliquant une
réduction de l'accessibilité d'une méthode durant l'héritage, ce qui est interdit par le
compilateur Java.
|
 |
 |
 |
You can see this in the modified version
of the Instrument example. Note that every method in the interface
is strictly a declaration, which is the only thing the compiler allows. In
addition, none of the methods in Instrument are declared as
public, but they’re automatically public
anyway:
|
 |
On peut le voir dans cette version modifiée de l'exemple
Instrument. Notons que chaque méthode de l'interface n'est
strictement qu'une déclaration, la seule chose que le compilateur permette. De plus, aucune des
méthodes d'Instrument n'est déclarée comme public, mais elles le
sont automatiquement.
|
 |
 |
 |
"+1">//: c08:music5:Music5.java color=#009900>// Interfaces. import java.util.*; color=#0000ff>interface Instrument { // Compile-time constant: color=#0000ff>int i = 5; color=#009900>// static & final // Cannot have method definitions: void play(); // Automatically public String what(); color=#0000ff>void adjust(); } class Wind implements Instrument { color=#0000ff>public color=#0000ff>void play() { System.out.println(color=#004488>"Wind.play()"); } public String what() { color=#0000ff>return color=#004488>"Wind"; } color=#0000ff>public color=#0000ff>void adjust() {} } class Percussion color=#0000ff>implements Instrument { color=#0000ff>public color=#0000ff>void play() { System.out.println(color=#004488>"Percussion.play()" ); } public String what() { color=#0000ff>return color=#004488>"Percussion"; } public color=#0000ff>void adjust() {} } class Stringed color=#0000ff>implements Instrument { color=#0000ff>public color=#0000ff>void play() { System.out.println(color=#004488>"Stringed.play()"); } public String what() { color=#0000ff>return color=#004488>"Stringed"; } color=#0000ff>public color=#0000ff>void adjust() {} } class Brass extends Wind { public void play() { System.out.println(color=#004488>"Brass.play()"); } public color=#0000ff>void adjust() { System.out.println(color=#004488>"Brass.adjust()"); } }
class Woodwind extends Wind { public void play() { System.out.println("Woodwind.play()"); } public String what() { return "Woodwind"; } }
public class Music5 { // Doesn't care about type, so new types // added to the system still work right: static void tune(Instrument i) { // ... i.play(); } static void tuneAll(Instrument[] e) { for(int i = 0; i < e.length; i++) tune(e[i]); } public static void main(String[] args) { Instrument[] orchestra = new Instrument[5]; int i = 0; // Upcasting during addition to the array: orchestra[i++] = new Wind(); orchestra[i++] = new Percussion(); orchestra[i++] = new Stringed(); orchestra[i++] = new Brass(); orchestra[i++] = new Woodwind(); tuneAll(orchestra); } } ///:~
|
 |
//: c08:music5:Music5.java // Interfaces. import java.util.*;
interface Instrument { // Constante compilée : int i = 5; // static & final // Définitions de méthodes interdites : void play(); // Automatiquement public String what(); void adjust(); }
class Wind implements Instrument { public void play() { System.out.println("Wind.play()"); } public String what() { return "Wind"; } public void adjust() {} }
class Percussion implements Instrument { public void play() { System.out.println("Percussion.play()"); } public String what() { return "Percussion"; } public void adjust() {} }
class Stringed implements Instrument { public void play() { System.out.println("Stringed.play()"); } public String what() { return "Stringed"; } public void adjust() {} }
class Brass extends Wind { public void play() { System.out.println("Brass.play()"); } public void adjust() { System.out.println("Brass.adjust()"); } }
class Woodwind extends Wind { public void play() { System.out.println("Woodwind.play()"); } public String what() { return "Woodwind"; } }
public class Music5 { // Le type n'est pas important, donc les nouveaux // types ajoutés au système marchent sans problème : static void tune(Instrument i) { // ... i.play(); } static void tuneAll(Instrument[] e) { for(int i = 0; i < e.length; i++) tune(e[i]); } public static void main(String[] args) { Instrument[] orchestra = new Instrument[5]; int i = 0; // Transtypage ascendant durant le stockage dans le tableau : orchestra[i++] = new Wind(); orchestra[i++] = new Percussion(); orchestra[i++] = new Stringed(); orchestra[i++] = new Brass(); orchestra[i++] = new Woodwind(); tuneAll(orchestra); } } ///:~
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |