Comment les Interfaces Java simulent-elles l'héritage multiple?

je lis" le tutoriel Java " (pour la 2e fois). Je viens de parcourir la section sur les Interfaces (encore), mais je ne comprends toujours pas comment les Interfaces Java simulent l'héritage multiple. Est-il une explication plus claire que ce qui est dans le livre?

71
demandé sur user 2010-08-24 17:01:41

21 réponses

supposez que vous avez 2 sortes de choses dans votre domaine: camions et cuisines

Les camions

ont une méthode driveTo() et une méthode Cook ().

supposons maintenant que Pauli décide de vendre des pizzas à l'arrière d'un camion de livraison. Il veut un truc avec lequel il peut conduire () et cuisiner ().

En C++, il serait d'utiliser l'héritage multiple pour ce faire.

en Java qui a été considéré comme trop dangereux donc vous peut hériter d'une classe principale, mais vous pouvez "hériter" des comportements des interfaces, qui sont pour ainsi dire des classes abstraites sans champs ni implémentations de méthodes.

ainsi, en Java, nous avons tendance à mettre en œuvre l'héritage multiple en utilisant les délégations:

Pauli sous-classe un camion et ajoute une cuisine au camion dans une variable membre appelée cuisine. Il implante L'interface de la cuisine en appelant la cuisine.cuire.)(

class PizzaTruck extends Truck implements Kitchen {
   Kitchen kitchen;

   public void cook(Food foodItem) {
      kitchen.cook(foodItem);
   }
}

C'est un homme heureux parce qu'il peut maintenant faire des choses comme;

pizzaTruck.driveTo(beach);
pizzaTruck.cook(pizzaWithExtraAnchovies);

Ok, cette histoire stupide était de faire le point qu'il ne s'agit pas d'une simulation d'héritage multiple, il s'agit d'héritage multiple réel avec la condition que vous pouvez seulement hériter le contrat, seulement hériter de classes de base abstraites vides qui sont appelées interfaces.

(mise à jour: avec la venue de les interfaces de méthodes par défaut peuvent maintenant également fournir certains comportements à être héréditaire)

147
répondu Peter Tillemans 2018-08-16 12:18:31

vous êtes probablement confus parce que vous voyez l'héritage multiple localement, en termes d'une classe héritant des détails de mise en œuvre de plusieurs parents. Ce n'est pas possible en Java (et conduit souvent à des abus dans les langues où c'est possible).

Les Interfaces

permettent l'héritage multiple de types , p.ex. un class Waterfowl extends Bird implements Swimmer peut être utilisé par d'autres classes comme si c'était un Bird et comme si c'était un Swimmer . C'est le sens le plus profond de l'héritage multiple: permettre à un objet d'agir comme s'il appartenait à plusieurs classes différentes à la fois.

18
répondu Michael Borgwardt 2010-08-24 13:11:15

voici un moyen d'obtenir un héritage multiple à travers des interfaces en java.

que faire?

Classe A étend B, C // ce n'est pas possible en java directement mais peut être réalisé indirectement.

class B{
   public void getValueB(){}
}

class C{
   public void getValueC(){}
}


interface cInterface{
   public getValueC();
}

class cChild extends C implemets cInterface{
    public getValueC(){

      // implementation goes here, call the super class's getValueC();

    }
}


// Below code is **like** class A extends B, C 
class A extends B implements cInterface{
   cInterface child =  new cChild();
   child.getValueC();
}
16
répondu challenger 2013-02-03 04:29:25

étant donné les deux interfaces ci-dessous...

interface I1 {
  abstract void test(int i);
}
interface I2 {
  abstract void test(String s);
}

nous pouvons implémenter les deux en utilisant le code ci-dessous...

public class MultInterfaces implements I1, I2 {
  public void test(int i) {
    System.out.println("In MultInterfaces.I1.test");
  }
  public void test(String s) {
    System.out.println("In MultInterfaces.I2.test");
  }
  public static void main(String[] a) {
    MultInterfaces t = new MultInterfaces();
    t.test(42);
    t.test("Hello");
  }
}

nous ne pouvons pas étendre deux objets, mais nous pouvons implémenter deux interfaces.

10
répondu david99world 2010-08-24 13:10:10
Les Interfaces

ne simulent pas les héritages multiples. Les créateurs de Java considèrent que l'héritage multiple est une erreur, il n'y a donc pas de telle chose en Java.

si vous voulez combiner la fonctionnalité de deux classes dans la composition d'un objet à usage unique. C'est-à-dire:

public class Main {
    private Component1 component1 = new Component1();    
    private Component2 component2 = new Component2();
}

et si vous voulez exposer certaines méthodes, définissez-les et laissez-les déléguer l'appel au contrôleur correspondant.

ici, les interfaces peuvent être utiles-si Component1 implémente l'interface Interface1 et Component2 met en œuvre Interface2 , vous pouvez définir

class Main implements Interface1, Interface2

de sorte que vous pouvez utiliser les objets de façon interchangeable lorsque le contexte le permet.

10
répondu Bozho 2010-08-24 13:34:17

vous savez quoi, venant du point de vue D'un dev JavaScript essayant de comprendre ce qui se passe avec ce truc, je voudrais souligner quelques choses et quelqu'un s'il vous plaît me dire ce que je manque ici si je suis loin de la cible.

Les Interfaces

sont très simples. Bêtement, incroyablement simple. Ils sont aussi stupidement, insanely simples que les gens pensent au départ, c'est pourquoi il y a tant de questions en double sur ce sujet exact parce que la seule raison leur utilisation a été rendue imprécise par les gens qui essayent d'en fabriquer plus qu'ils ne le sont et il y a une mauvaise utilisation généralisée dans toutes les bases de code Java côté serveur auxquelles j'ai été exposé.

Alors, pourquoi voudriez-vous utiliser? La plupart du temps, non. Vous ne voudriez certainement pas les utiliser tout le temps comme beaucoup semblent le penser. Mais avant d'en arriver à vous, nous allons parler de ce qu'ils ne le sont PAS.

les Interfaces ne sont pas:

  • d'une manière ou d'une autre, une solution de contournement pour toute sorte de mécanisme d'héritage qui fait défaut à Java. Ils n'ont rien à voir avec l'héritage, ils ne l'ont jamais fait, et ne simulent en aucun cas quelque chose comme l'héritage.
  • forcément quelque chose qui vous aide avec les choses que vous avez écrites, autant que cela aide l'autre gars à écrire quelque chose destiné à être interfacé par vos choses.

Ils sont vraiment aussi simple que vous pensez qu'ils sont sur premier coup d'œil. Les gens abusent bêtement tout le temps, donc c'est difficile de comprendre ce que c'est. C'est juste de la validation/des tests. Une fois que vous avez écrit quelque chose se conforme à une interface et fonctionne, enlever ce code "implements" ne cassera rien.

mais si vous utilisez les interfaces correctement, vous ne voudriez pas l'enlever parce que l'avoir donne au prochain développeur un outil pour écrire une couche d'accès pour un autre ensemble de bases de données ou de services web qu'ils veulent le reste de votre application pour continuer à utiliser parce qu'ils savent que leur classe échouera jusqu'à ce qu'ils obtiennent le 100% complet-comme prévu-l'interface en place. Toutes les interfaces font est de valider votre classe et d'établir que vous avez en fait mis en œuvre une interface comme vous l'aviez promis. Rien de plus.

ils sont aussi portables. En exposant vos définitions d'interface vous pouvez donner aux gens qui veulent utiliser votre code non exposé un ensemble de méthodes à se conformer afin que leurs objets de l'utiliser correctement. Ils n'ont pas à implémenter les interfaces. Ils pourraient les noter sur un bout de papier et vérifier ça. Mais avec l'interface vous avez plus d'une garantie rien ne va essayer de fonctionner jusqu'à ce qu'il ait une version correcte de l'interface en question.

donc, n'importe quelle interface ne sera probablement jamais implémentée plus d'une fois? Complètement inutile. Multi-héritage? Arrête de chercher cet arc-en-ciel. Java évite pour une raison en premier lieu de plus, les objets compostés/agrégés sont plus flexibles à bien des égards. Cela ne veut pas dire que les interfaces ne peuvent pas vous aider à modéliser de la manière que l'héritage multiple permet, mais ce n'est vraiment pas l'héritage de quelque façon que ce soit et ne devrait pas être vu comme tel. C'est juste une garantie que votre code ne fonctionnera pas tant que vous n'aurez pas mis en place toutes les méthodes que vous avez établies.

6
répondu Erik Reppen 2013-02-05 19:40:02

c'est assez simple. Vous pouvez implémenter plus d'une interface dans un type. Ainsi, par exemple, vous pouvez avoir une implémentation de List qui est aussi une instance de Deque (et Java le fait... LinkedList ).

Vous ne pouvez pas hériter implémentations à partir de plusieurs parents (prolongation de plusieurs classes). Déclarations (signatures de méthode) ne sont pas un problème.

5
répondu Mark Peters 2010-08-24 13:04:19

ce n'est pas une simulation d'héritage multiple. En java, vous ne pouvez pas hériter de deux classes, mais si vous implémentez deux interfaces "il semble que vous avez hérité de deux classes différentes" parce que vous pouvez utiliser votre classe comme n'importe laquelle de vos deux intefaces.

par exemple

interface MyFirstInteface{
    void method1();
}
interface MySecondInteface{
    void method2();
}
class MyClass implements MyFirstInteface, MySecondInteface{
    public void method1(){
        //Method 1
    }
    public void method2(){
        //Method 2
    }

    public static void main(String... args){
        MyFirstInterface mfi = new MyClass();
        MySecondInterface msi = new MyClass();
    }
}

cela va fonctionner et vous pouvez utiliser mfi et msi, il semble comme un héritage multi, mais ce n'est pas parce que vous n'héritez rien, vous venez de réécrire public les méthodes fournies par les interfaces.

3
répondu Colin Hebert 2010-08-24 13:06:10

vous devez être précis:

Java permet l'héritage multiple de l'interface, mais seulement l'héritage unique de la mise en œuvre.

vous faites héritage multiple d'interface en Java comme ceci:

public interface Foo
{
    String getX(); 
}

public interface Bar
{
    String getY();
}

public class MultipleInterfaces implements Foo, Bar
{
    private Foo foo;
    private Bar bar;

    public MultipleInterfaces(Foo foo, Bar bar)
    {
        this.foo = foo;
        this.bar = bar;
    }

    public String getX() { return this.foo.getX(); }
    public String getY() { return this.bar.getY(); }
}
3
répondu duffymo 2010-08-24 13:18:45

d'ailleurs, la raison pour laquelle Java n'implémente pas l'héritage multiple complet est qu'il crée des ambiguïtés. Supposons que vous puissiez dire "a s'étend B, C", et puis B et C ont tous les deux une fonction"void f(int)". Quelle mise en œuvre hérite-t-on? Avec L'approche de Java, vous pouvez implémenter n'importe quel nombre d'interfaces, mais les interfaces ne déclarent qu'une signature. Donc si deux interfaces incluent des fonctions avec la même signature, bien, votre classe doit implémenter une fonction avec cette signature. Si interfaces vous héritez d'avoir des fonctions avec des signatures différentes, les fonctions n'ont rien à voir les uns avec les autres, donc il n'est pas question d'un conflit.

je ne dis pas que c'est le seul moyen. C++ implémente le véritable héritage multiple en établissant des règles de priorité dont l'implémentation gagne. Mais les auteurs de Java a décidé d'éliminer l'ambiguïté. Que ce soit à cause d'une croyance philosophique que cela a fait pour un code plus propre, ou parce qu'ils ne voulaient pas faire tout le travail, je ne sais pas.

3
répondu Jay 2010-08-24 13:47:44

il n'est pas juste de dire que les interfaces "simulent" l'héritage multiple.

bien sûr, votre type peut implémenter plusieurs interfaces et agir comme beaucoup de types différents polymorphiquement. Cependant, vous n'hériterez évidemment pas du comportement ou des implémentations en vertu de cet arrangement.

regardez généralement la composition où vous pensez que vous pourriez avoir besoin d'héritage multiple.

ou une solution potentielle pour réaliser quelque chose de multiple héritage comme est L'interface de Mixin - http://csis.pace.edu/~bergin/patterns/multipleinheritance.html . À utiliser avec précaution!

2
répondu Benjamin Wootton 2010-08-24 13:10:01

ils ne le font pas.

je pense que la confusion vient des gens qui croient que la mise en place d'une interface constitue une forme d'héritage. Il ne le fait pas; la mise en œuvre peut simplement être vide, aucun comportement n'est forcé par l'acte ou garanti par un contrat. Un exemple typique est Clonable-interface, qui tout en faisant allusion à beaucoup de fonctionnalité grande, qui définit si peu que c'est essentiellement inutile et potentiellement dangereux.

qu'héritez-vous en implémentant une interface? Bubkes! Donc, à mon avis, arrêter d'utiliser les mots interface et héritage dans la même phrase. Comme L'a dit Michael Borgwartt, une interface n'est pas une définition mais un aspect.

2
répondu mikek 2010-08-24 13:38:14

vous pouvez en fait" hériter " de plusieurs classes de béton s'ils implémentent eux-mêmes des interfaces. innerclasses vous aider à atteindre:

interface IBird {
    public void layEgg();
}

interface IMammal {
    public void giveMilk();
}

class Bird implements IBird{
    public void layEgg() {
        System.out.println("Laying eggs...");
    }
}

class Mammal implements IMammal {
    public void giveMilk() {
        System.out.println("Giving milk...");
    }
}

class Platypus implements IMammal, IBird {

    private class LayingEggAnimal extends Bird {}
    private class GivingMilkAnimal extends Mammal {}

    private LayingEggAnimal layingEggAnimal = new LayingEggAnimal();

    private GivingMilkAnimal givingMilkAnimal = new GivingMilkAnimal();

    @Override
    public void layEgg() {
        layingEggAnimal.layEgg();
    }

    @Override
    public void giveMilk() {
        givingMilkAnimal.giveMilk();
    }

}

2
répondu SHOJAEI BAGHINI 2012-12-13 20:14:20

Je ne pense pas.

héritage est spécifiquement une relation axée sur la mise en œuvre entre les mises en œuvre. Les Interfaces ne fournissent aucune information sur la mise en œuvre, mais définissent plutôt un type. Pour avoir l'héritage, vous devez spécifiquement hériter certains comportements ou attributs d'une classe de parent.

je crois qu'il y a une question ici quelque part spécifiquement sur le rôle des interfaces et de l'héritage multiple, mais je ne pouvez pas le trouver maintenant...

1
répondu Thomas Owens 2010-08-24 13:07:56

il n'y a vraiment pas de simulation d'héritage multiple en Java.

les gens diront parfois que vous pouvez simuler l'héritage multiple en utilisant des Interfaces parce que vous pouvez implémenter plus d'une interface par classe, et puis utiliser la composition (plutôt que l'héritage) dans votre classe pour atteindre les comportements des classes multiples dont vous essayiez d'hériter pour commencer.

1
répondu Justin Niessner 2010-08-24 13:10:14

si cela a du sens dans votre modèle d'objet, vous pouvez bien sûr hériter d'une classe et implémenter 1 ou plusieurs interfaces.

1
répondu Benjamin Wootton 2010-08-24 13:20:14

il y a des cas où l'héritage multiple devient très pratique et difficile à remplacer par des interfaces sans écrire plus de code. Par exemple, il existe des applications Android qui utilisent des classes dérivées D'Activity et d'autres de FragmentActivity dans la même application. Si vous avez une fonctionnalité particulière que vous voulez partager dans une classe commune, en Java vous devrez dupliquer du code au lieu de laisser les classes d'activités et FragmentsActivity enfants dériver de la même classe de SharedFeature. Et la une mauvaise implémentation des génériques en Java n'aide pas non plus car écrire ce qui suit est illégal:

public class SharedFeature<T> extends <T extends Activity>

...
...
1
répondu Sergiob 2013-02-20 08:35:08

il n'y a pas de support pour l'héritage multiple en java.

cette histoire de prise en charge de l'héritage multiple en utilisant l'interface est ce que nous développeurs concocté. Interface offre plus de flexibilité que les classes de béton et nous avons la possibilité d'implémenter des interfaces multiples en utilisant une seule classe. C'est par accord que nous adhérons à deux plans pour créer une classe.

c'est essayer de se rapprocher de l'héritage multiple. Ce que nous faisons est de mettre en œuvre plusieurs interface, ici nous n'étendons (n'héritons) rien. La classe implementing est celle qui va ajouter les propriétés et le comportement. Il ne s'agit pas d'obtenir l'implémentation libre des classes parentes. Je dirais simplement qu'il n'y a pas de support pour l'héritage multiple en java.

1
répondu Vivek Sadh 2013-05-18 10:55:11

je voudrais souligner quelque chose qui m'a mordu dans le dos, venant de C++ où vous pouvez facilement hériter de nombreuses implémentations aussi.

ayant une interface" large "avec de nombreuses méthodes signifie que vous aurez à mettre en œuvre beaucoup de méthodes dans vos classes de béton et vous ne pouvez pas partager ces facilement à travers les implémentations.

par exemple:

interface Herbivore {
    void munch(Vegetable v);
};

interface Carnivore {
    void devour(Prey p);
}

interface AllEater : public Herbivore, Carnivore { };

class Fox implements AllEater {
   ... 
};

class Bear implements AllEater {
   ...
};

dans cet exemple, Renard et ours ne peut pas partager une implémentation de base commune pour ses deux méthodes d'interface munch et devour .

si les implémentations de base ressemblent à ceci, nous aimerions peut-être les utiliser pour Fox et Bear :

class ForestHerbivore implements Herbivore
    void munch(Vegetable v) { ... }
};

class ForestCarnivore implements Carnivore
    void devour(Prey p) { ... }
};

mais on ne peut pas hériter de ces deux-là. Les implémentations de base doivent être des variables membres dans la classe et les méthodes définies peuvent être transmises à cela. I. e:

class Fox implements AllEater {
    private ForestHerbivore m_herbivore;
    private ForestCarnivore m_carnivore;

    void munch(Vegetable v) { m_herbivore.munch(v); }
    void devour(Prey p) { m_carnivore.devour(p); }
}

difficile si les interfaces se développent (c.-à-d. plus de 5-10 méthodes...)

une meilleure approche consiste à définir une interface comme une agrégation d'interfaces:

interface AllEater {
    Herbivore asHerbivore();
    Carnivore asCarnivore();
}

cela signifie que Fox et Bear n'ont qu'à implémenter ces deux méthodes, et les interfaces et classes de base peuvent croître indépendamment de l'interface agrégée AllEater qui concerne les classes d'implémentation.

moins accouplement de cette façon, si elle fonctionne pour votre application.

1
répondu Macke 2014-03-27 08:49:49

Non, Java ne supporte pas l'héritage multiple. Ni en classe, ni à l'aide de l'interface. Consulter ce lien pour plus d'infos https://devsuyed.wordpress.com/2016/07/21/does-java-support-multiple-inheritance

1
répondu Suyed Dalvi 2016-07-21 11:23:50

je dois aussi dire que Java ne supporte pas les héritages multiples.

vous devez différencier le sens entre les mots clés extends et implements en Java. Si nous utilisons extends , nous héritons en fait de la classe après ce mot-clé. Mais pour que tout soit simple, nous ne pouvons pas utiliser extends plus d'une fois. Mais vous pouvez implémenter autant d'Interfaces que vous le souhaitez.

si vous implémentez une interface, il y a un zéro possibilité que vous manquiez l'implémentation de toutes les méthodes dans chaque interface (Exception: implémentations par défaut des méthodes d'interface introduites dans Java 8) donc, vous êtes maintenant pleinement conscient de ce qui se passe avec les choses que vous avez intégré à votre nouvelle classe.

pourquoi Java ne permet pas l'héritage multiple est en fait, l'héritage multiple rend le code quelque peu complexe. Parfois, deux méthodes de classes parents peuvent être en conflit en raison d'avoir le même signature. Mais si vous êtes forcé de mettre en œuvre toutes les méthodes manuellement, vous obtiendrez la pleine compréhension de ce qui se passe, comme je l'ai mentionné ci-dessus. Il rend votre code plus compréhensible pour vous.

si vous avez besoin de plus d'informations sur les interfaces Java, consultez cet article, http://www.geek-programmer.com/introduction-to-java-interfaces /

1
répondu user7338196 2017-04-09 07:23:57