159 votes

Comment sont les interfaces de Java?

Donc disons que j'ai cette interface:

public interface IBox
{
   public void setSize(int size);
   public int getSize();
   public int getArea();
  //...and so on
}

Et j'ai une classe qui l'implémente:

public class Rectangle implements IBox
{
   private int size;
   //Methods here
}

Si je voulais utiliser l'interface IBox, je ne peux pas vraiment en créer une instance, dans le moyen:

public static void main(String args[])
{
    Ibox myBox=new Ibox();
}

droit? Donc, j'avais fait faire ceci:

public static void main(String args[])
{
    Rectangle myBox=new Rectangle();
}

Si cela est vrai, alors le seul but d'interfaces est de faire en sorte que la classe qui implémente une interface a eu la bonne méthode, comme décrit par une interface? Ou est-il tout autre utilisation des interfaces?

143voto

morgancodes Points 8569

Les Interfaces sont une façon de rendre votre code plus souple. Ce que vous faire est ceci:

Ibox myBox=new Rectangle();

Puis, plus tard, si vous décidez que vous souhaitez utiliser un autre type de boîte (peut-être il ya une autre bibliothèque, avec un meilleur type de boîte), vous passez votre code:

Ibox myBox=new OtherKindOfBox();

Une fois que vous vous habituez à elle, vous trouverez que c'est un grand (essentielle) chemin du travail.

Une autre raison est, par exemple, si vous souhaitez créer une liste de boîtes et d'effectuer une opération sur chacun d'eux, mais que vous voulez la liste de contenir différents types de boîtes. Sur chaque boîte que vous pouvez faire:

myBox.close()

(en supposant que IBox a une méthode close ()) même si la classe réelle de myBox change en fonction de la zone que vous êtes dans l'itération.

124voto

Michael Borgwardt Points 181658

Ce qui rend les interfaces utiles, c'est pas le fait que "vous pouvez changer votre esprit et à l'utilisation d'une mise en œuvre différente, plus tard, et de ne changer que le seul endroit où l'objet est créé". C'est un non-problème.

La vraie question est déjà dans le nom: ils définissent une interface que n'importe qui peut mettre en œuvre pour utiliser tout le code qui fonctionne sur cette interface. Le meilleur exemple est - java.util.Collections qui fournit toutes sortes de méthodes utiles qui fonctionnent uniquement sur les interfaces, telles que sort() ou reverse() pour List. Le point ici est que ce code peut maintenant être utilisé pour trier ou d'inverser toute classe qui implémente l' List interfaces - pas seulement ArrayList et LinkedList, mais aussi classes que vous écrivez vous-même, ce qui peut être mis en œuvre de manière les personnes qui ont écrit java.util.Collections n'ont jamais imaginé.

De la même manière, vous pouvez écrire du code qui fonctionne sur le bien-connu des interfaces, des interfaces ou que vous définissez, et d'autres personnes peuvent utiliser votre code sans avoir à vous demander de soutenir leurs classes.

Une autre utilisation courante des interfaces pour les Rappels. Par exemple, java.swing.table.TableCellRenderer, ce qui vous permet d'influencer la façon dont une Balançoire tableau affiche les données dans une colonne spécifique. Implémenter cette interface, passer d'une instance à l' JTable, et à un certain moment pendant le rendu de la table, votre code sera appelée à faire ses trucs.

120voto

peevesy Points 371

L'une des nombreuses utilisations que j'ai lu est là que c'est difficile sans multi-héritage-l'utilisation des interfaces en Java :

class Animal
{
void walk() { } 
....
.... //other methods and finally
void chew() { } //concentrate on this
} 

Maintenant, Imaginer un cas où:

class Reptile extends Animal 
{ 
//reptile specific code here
} //not a problem here

mais,

class Bird extends Animal
{
...... //other Bird specific code
} //now Birds cannot chew so this would a problem in the sense Bird classes can also call chew() method which is unwanted

Une meilleure conception de l'être:

class Animal
{
void walk() { } 
....
.... //other methods 
} 

L'Animal n'a pas le mâcher() la méthode et la place est mis dans une interface :

interface Chewable {
void chew();
}

et de Reptiles ont la classe en œuvre et de ne pas les Oiseaux (les Oiseaux ne peuvent pas mâcher) :

class Reptile extends Animal implements Chewable { } 

et en cas où des Oiseaux tout simplement:

class Bird extends Animal { }

48voto

Apocalisp Points 22526

Le but des interfaces, polymorphisme, une.k.un. type de substitution. Par exemple, pour la méthode suivante:

public void scale(IBox b, int i) {
   b.setSize(b.getSize() * i);
}

Lors de l'appel de l' scale méthode, vous pouvez fournir une valeur qui est d'un type qui implémente l' IBox interface. En d'autres termes, si Rectangle et Square à la fois mettre en oeuvre IBox, vous pouvez fournir soit une Rectangle ou Square où un IBox est attendue.

33voto

Jared Points 7800

Les Interfaces permettent de langages statiquement typés à l'appui de polymorphisme. Orientée Objet puriste veux insister sur le fait qu'une langue doit fournir à l'héritage, l'encapsulation, modularité et le polymorphisme pour être un complet langage Orienté Objet. Dans dynamiquement typés ou de canard tapé langues (comme Smalltalk,) le polymorphisme est trivial; toutefois, dans les langages à typage statique (comme Java ou C#,) le polymorphisme est loin d'être négligeable (en fait, sur la surface, il semble être en contradiction avec la notion de typage fort.)

Laissez-moi vous montrer:

Dans un dynamiquement typés (ou de canard tapé) langue (Smalltalk), toutes les variables sont des références à des objets (rien de moins et rien de plus.) Donc, en Smalltalk, je peux faire ceci:

|anAnimal|    
anAnimal := Pig new.
anAnimal makeNoise.

anAnimal := Cow new.
anAnimal makeNoise.

Ce code:

  1. Déclare une variable locale appelée anAnimal (notez que nous N'avons PAS de spécifier le TYPE de la variable - toutes les variables sont des références à un objet, rien de plus et rien de moins.)
  2. Crée une nouvelle instance de la classe nommée "Cochon"
  3. Attribue cette nouvelle instance de Porc à la variable anAnimal.
  4. Envoie le message makeNoise pour le porc.
  5. Répète le tout à l'aide d'une vache, mais en l'assignant à la même variable que le Cochon.

Le même code Java ressemblerait à quelque chose comme ceci (en faisant l'hypothèse que le Canard et la Vache sont des sous-classes d'Animaux:

Animal anAnimal = new Pig();
duck.makeNoise();

anAnimal = new Cow();
cow.makeNoise();

C'est bien beau tout ça, jusqu'à ce que nous introduisons la classe de Légumes. Les légumes ont certains de le même comportement de l'Animal, mais pas tous. Par exemple, à la fois Animales et Végétales pourraient être en mesure de croître, mais à l'évidence les légumes ne pas faire de bruit et les animaux ne peuvent pas être récoltés.

En Smalltalk, nous pouvons écrire ceci:

|aFarmObject|
aFarmObject := Cow new.
aFarmObject grow.
aFarmObject makeNoise.

aFarmObject := Corn new.
aFarmObject grow.
aFarmObject harvest.

Cela fonctionne parfaitement bien dans Smalltalk parce que c'est le canard tapé (si ça marche comme un canard, et des charlatans comme un canard, c'est un canard.) Dans ce cas, lorsqu'un message est envoyé à un objet, une recherche est effectuée sur le récepteur de la méthode de la liste, et si une méthode de correspondance est trouvée, elle est appelée. Si non, une sorte de NoSuchMethodError exception est levée, mais tout se fait au moment de l'exécution.

Mais en Java, un langage statiquement typé, ce type de peut-on attribuer à notre variable? Le maïs doit hériter de Légumes, à l'appui de croître, mais ne peut pas hériter de l'Animal, car il ne font pas de bruit. La vache a besoin d'hériter de l'Animal à l'appui makeNoise, mais ne peut pas hériter de Légumes car il ne faut pas mettre en œuvre la récolte. Il semble que nous ayons besoin de l'héritage multiple - la possibilité d'hériter de plus d'une classe. Mais qui s'avère être assez difficile pour le langage, parce que de tous les cas de bord que les pop-up (ce qui se produit lorsque plus d'un parallèle de la superclasse de mettre en œuvre la même méthode?, etc.)

Que les interfaces...

Si nous faisons Animales et Végétales classes, avec la mise en œuvre de chaque Cultivables, nous pouvons déclarer que notre Vache est l'Animal et notre Maïs est un Légume. On peut aussi déclarer qu'à la fois Animales et Végétales sont Cultivables. Qui nous permet d'écrire ce à croître tout:

List<Growable> list = new ArrayList<Growable>();
list.add(new Cow());
list.add(new Corn());
list.add(new Pig());

for(Growable g : list) {
   g.grow();
}

Et il nous permet de faire cela, de faire des bruits d'animaux:

List<Animal> list = new ArrayList<Animal>();
list.add(new Cow());
list.add(new Pig());
for(Animal a : list) {
  a.makeNoise();
}

L'avantage pour le canard de type de langage est que vous obtenez vraiment sympa polymorphisme: tous d'une classe a à faire pour fournir comportement est de fournir la méthode. Tant que tout le monde joue de nice, et envoie uniquement les messages qui correspondent aux méthodes définies, tout est bon. L'inconvénient est que le type d'erreur ci-dessous n'est pas pris jusqu'à l'exécution:

|aFarmObject|
aFarmObject := Corn new.
aFarmObject makeNoise. // No compiler error - not checked until runtime.

Statiquement typé langues fournir beaucoup mieux "de la programmation par contrat", parce qu'ils vont attraper les deux types d'erreur ci-dessous au moment de la compilation:

// Compiler error: Corn cannot be cast to Animal.
Animal farmObject = new Corn();  
farmObject makeNoise();

--

// Compiler error: Animal doesn't have the harvest message.
Animal farmObject = new Cow();
farmObject.harvest();

Donc....pour résumer:

  1. L'implémentation de l'Interface vous permet de spécifier quels sont les types de choses que les objets peuvent faire (interaction) et l'héritage de Classe permet de spécifier la façon dont les choses devraient être faites (mise en œuvre).

  2. Les Interfaces de nous donner de nombreux avantages de la "vraie" polymorphisme, sans sacrifier le compilateur le type de la vérification.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X