Pourquoi L'héritage Multiple N'est pas autorisé en Java ou C#?

je sais que L'héritage multiple n'est pas autorisé en Java et C#. Beaucoup de livres disent que l'héritage multiple n'est pas autorisé. Mais il peut être mis en œuvre en utilisant des interfaces. On ne discute pas des raisons pour lesquelles cela n'est pas permis. Est-ce que quelqu'un peut me dire précisément pourquoi cela n'est pas autorisé?

97
demandé sur Jon Schneider 2009-06-15 13:49:13

17 réponses

la réponse courte est: parce que les concepteurs de langue ont décidé de ne pas.

fondamentalement, il semble que les deux concepteurs .NET et Java n'ont pas permis l'héritage multiple parce qu'ils ont raisonné que l'ajout de MI ajouté trop de complexité aux langues tout en fournissant trop peu d'avantage .

pour une lecture plus ludique et approfondie, il y a quelques articles disponibles sur le web avec des interviews de une partie de la langue des designers. Par exemple, pour .NET, Chris Brumme (qui a travaillé à MS sur le CLR) a expliqué les raisons pour lesquelles ils ont décidé de ne pas:

  1. différentes langues ont en fait des attentes différentes quant à la façon dont les langues MI travail. Par exemple, comment les conflits sont résolu et si bases dupliquées sont fusionnées ou redondantes. Avant que nous puissions mettre en œuvre MI dans le CLR, nous devons faire une étude de toutes les langues, la figure hors les concepts communs, et de décider comment les exprimer dans un langue de manière neutre. Nous aussi décider si MI appartient à la CLS et ce que cela signifierait pour des langues qui ne veulent pas de ce concept (probablement VB.NET, par exemple). De bien sûr, c'est l'entreprise, nous sommes en comme une langue commune runtime, mais nous n'ai pas eu à le faire pour MI encore.

  2. le nombre d'endroits où L'IM est vraiment approprié est fait assez petit. Dans de nombreux cas, plusieurs l'héritage de l'interface peuvent obtenir le travail fait à la place. Dans d'autres cas, vous pouvez être capable d'utiliser l'encapsulation et délégation. Si nous devions ajouter une construction légèrement différente, comme mixin, serait-ce en fait être plus puissant?

  3. l'héritage de la mise en œuvre Multiple injecte beaucoup de complexité dans le application. Cette complexité les impacts de la coulée, la mise en page, envoi, champ accès, sérialisation, identité comparaisons, vérifiabilité, réflexion, génériques, et probablement beaucoup d'autres endroits.

Vous pouvez lire l'article complet ici.

pour Java, vous pouvez lire cet article :

Les raisons de l'omission de plusieurs héritage du langage Java la plupart proviennent de la " simple, objet objectif orienté et familier. En tant que langage simple, les créateurs de Java voulait un langage que la plupart des développeurs pourrait saisir sans vaste formation. À cette fin, ils ont travaillé à l' rendre le langage aussi similaire à C++ que possible (familier) sans porter sur la complexité inutile de C++ (simple.)

selon les concepteurs, multiple l'héritage provoque plus de problèmes et la confusion ne résout rien. Donc ils ont coupé héritage multiple de la langue (tout comme ils coupent opérateur surcharger.) Les concepteurs vaste L'expérience du C++ leur a appris que l'héritage multiple n'en valait pas la peine. mal.

131
répondu Razzie 2017-10-13 20:09:20

héritage Multiple de implémentation est ce qui n'est pas autorisé.

le problème est que le compilateur/runtime ne peut pas comprendre ce qu'il faut faire si vous avez une classe Cowboy et une classe Artist, les deux avec implémentations pour la méthode draw (), et ensuite vous essayez de créer un nouveau type CowboyArtist. Ce qui se produit lorsque vous appelez la méthode draw ()? Quelqu'un est couché mort dans la rue, ou vous avez une belle aquarelle?

I crois que ça s'appelle le diamant double héritage problème.

83
répondu duffymo 2009-06-15 09:52:59

raison: Java est très populaire et facile à coder, en raison de sa simplicité.

donc ce que jamais les développeurs java se sentent difficiles et compliqués à comprendre pour les programmeurs, ils ont essayé de l'éviter. Un tel type de propriété est l'héritage multiple.

  1. ils évitaient les pointeurs
  2. ils évitèrent les héritages multiples.

problème avec héritage multiple: problème de diamant.

exemple :

  1. supposer que la classe A a un plaisir de méthode(). la Classe B et la Classe C proviennent de la classe A.
  2. et à la fois les classes B et c, l'emporte sur la méthode fun().
  3. supposons maintenant que la classe D hérite à la fois de la Classe B et de la classe C. (hypothèse juste)
  4. créer un objet pour la classe D.
  5. D d = new D ();
  6. et essayez d'accéder à d.fun(); => il a fait appel de la classe B est amusant() ou la classe C est amusant()?

C'est l'ambiguïté qui existe dans le problème du diamant.

il n'est pas impossible de résoudre ce problème, mais il crée plus de confusion et de complexités pour le programmeur tout en le lisant. Elle cause plus de problème qu'il tente de résoudre.

Note : mais de n'importe quelle façon vous pouvez toujours implémenter l'héritage multiple indirectement en utilisant des interfaces.

19
répondu user1923551 2013-12-12 07:34:59

parce que Java a une philosophie de conception très différente de C++. (Je ne vais pas discuter de C# ici.)

dans la conception de C++, Stroustrup a voulu inclure des fonctionnalités utiles, quelle que soit la façon dont elles pouvaient être utilisées. Il est possible de foirer grand-temps avec l'héritage multiple, la surcharge de l'opérateur, les gabarits, et diverses autres fonctionnalités, mais il est également possible de faire de très bonnes choses avec eux.

la philosophie de conception Java est de l'accent sur la sécurité dans les constructions de langage. Le résultat est qu'il y a des choses qui sont beaucoup plus embarrassantes à faire, mais vous pouvez être beaucoup plus sûr que le code que vous regardez signifie ce que vous pensez qu'il fait.

en outre, Java était dans une large mesure une réaction de C++ et Smalltalk, les langages OO les plus connus. Il y a beaucoup d'autres langues OO (le Lisp commun était en fait le premier à être standardisé), avec différents systèmes oo qui gèrent mieux le MI.

sans oublier qu'il est tout à fait possible de faire L'IM en Java, en utilisant des interfaces, la composition et la délégation. C'est plus explicite qu'en C++, et est donc plus maladroit à utiliser mais vous obtiendrez quelque chose que vous êtes plus susceptible de comprendre à première vue.

Il n'y a pas de bonne réponse ici. Il y a des réponses différentes, et celle qui est meilleure pour une situation donnée dépend des applications et des préférences individuelles.

13
répondu David Thornley 2009-06-15 18:01:29

la principale raison (bien qu'elle ne soit pas la seule) pour laquelle les gens s'écartent de L'IM est ce qu'on appelle le" problème du diamant " qui mène à l'ambiguïté dans votre mise en œuvre. Cet article de wikipedia le discute et l'explique mieux que je ne le pourrais. MI peut aussi conduire à un code plus complexe, et beaucoup de concepteurs OO prétendent que vous n'avez pas besoin de MI, et si vous l'utilisez, votre modèle est probablement faux. Je ne suis pas sûr d'être d'accord avec ce dernier point, mais garder les choses simples est toujours un bon plan.

12
répondu Steve Haigh 2015-02-27 15:45:35

En C++ héritage multiple a été l'un des principaux maux de tête lorsque mal utilisés. Pour éviter ces problèmes de design populaire, plusieurs interfaces ont été" héritées " à la place dans les langues modernes (java, C#).

8
répondu inazaruk 2009-06-15 09:56:11

L'héritage Multiple est

  • difficile à comprendre
  • difficile à déboguer (par exemple, si vous mélangez des classes à partir de cadres multiples qui ont des méthodes identiques nommées en profondeur, des synergies tout à fait inattendues peuvent se produire)
  • facile à mal utiliser
  • pas vraiment que utile
  • difficile à mettre en œuvre, surtout si vous voulez qu'il fait correctement et efficacement

par conséquent, il peut être considéré comme un choix judicieux de pas inclure L'héritage Multiple dans le langage Java.

8
répondu mfx 2009-06-15 11:14:29

une autre raison est qu'un seul héritage rend la coulée triviale, n'émettant aucune instruction de montage (autre que la vérification de la compatibilité des types lorsque requis). Si vous aviez plusieurs héritages, vous auriez besoin de comprendre où dans la classe de l'enfant un certain parent commence. La performance est donc certainement un avantage (mais pas le seul).

5
répondu Blindy 2009-06-15 10:02:47

je prends l'affirmation que "l'héritage Multiple n'est pas autorisé en Java" avec une pincée de sel.

l'Héritage Multiple est défini lorsqu'un "Type" hérite de plusieurs "Types". Et les interfaces sont également classées en tant que types comme ils ont un comportement. Donc Java a un héritage multiple. Juste que c'est plus sûr.

4
répondu Rig Veda 2009-06-15 17:27:38

chargement dynamique des classes rend la mise en œuvre de l'héritage multiple difficile.

en java en fait, ils ont évité la complexité de l'héritage multiple à la place en utilisant l'héritage unique et l'interface. Complexité de l'héritage multiple est très élevé dans une situation comme ci-dessous expliqué

diamant problème de l'héritage multiple. Nous avons deux classes B et C héritant de A. supposons que B et c supplantent une méthode héritée et qu'ils fournissent leur propre mise en œuvre. D hérite à la fois de B et C en faisant plusieurs héritages. D devrait hériter que la méthode overridden, jvm ne peut pas décider quelle méthode overridden sera utilisée?

dans C++ les fonctions virtuelles sont utilisées pour gérer et nous devons le faire explicitement.

cela peut être évité en utilisant des interfaces, il n'y a pas de corps de méthode. Les Interfaces ne peuvent pas être instanciated-ils ne peuvent être implémentés que par classes ou étendus par d'autres interfaces.

4
répondu sujith s 2013-01-12 11:44:43

dans les vieux jours ('70s) quand L'informatique était plus de Science et moins de production de masse les programmeurs ont eu le temps de penser à la bonne conception et à la bonne mise en œuvre et en conséquence les produits (programms) ont eu de haute qualité ( par exemple. TCP/IP de la conception et de la mise en œuvre ). De nos jours, lorsque tout le monde est à la programmation, et les gestionnaires sont en train de changer les spécifications avant les délais, les problèmes subtils comme celui décrit dans le lien Wikipédia de Steve Haigh post sont difficiles à suivre; par conséquent, "l'héritage multiple" est limitée par la conception du compilateur. Si vous l'aimez, vous pouvez toujours utiliser C++ .... et ont toute la liberté que vous voulez :)

3
répondu 2009-06-15 10:31:10

en fait l'héritage multiple se présentera à la complexité si les classes héritées ont la même fonction. ie le compilateur aura une confusion que l'on doit choisir (problème de diamant). Ainsi, en Java, cette complexité a enlevé et a donné l'interface pour obtenir la fonctionnalité comme l'héritage multiple a donné. Nous pouvons utiliser l'interface

3
répondu Jinu 2014-12-05 09:59:44

Java a concept, c'est à dire le polymorphisme. Il existe 2 types de polymorphisme en java. Il y a surcharge de la méthode et dépassement de la méthode. Parmi eux, la méthode de dépassement se produit avec super-et la relation de sous-classe. Si nous créons un objet d'une sous-classe et invoquons la méthode de la superclasse, et si la sous-classe s'étend sur plus d'une classe, Quelle méthode de la super-classe devrait être appelée?

ou, tout en appelant le constructeur de superclasse par super() , qui super Classe constructeur seront appelés?

ces décisions sont impossibles par les fonctionnalités actuelles de l'API java. donc, l'héritage multiple n'est pas autorisé en java.

2
répondu Abhay Kokate 2012-10-30 18:04:28

L'héritage Multiple N'est pas autorisé en Java directement , mais par l'intermédiaire d'interfaces il est autorisé.

raison:

succession Multiple: introduit plus de complexité et d'ambiguïté.

Interfaces: les Interfaces sont des classes complètement abstraites en Java qui vous fournissent une façon uniforme de bien délimiter la structure ou le fonctionnement interne de votre programme à partir de son interface accessible au public, avec pour conséquence une plus grande flexibilité et un code réutilisable ainsi qu'un contrôle accru sur la façon dont vous créez et interagissez avec d'autres classes.

plus précisément, ils sont une construction spéciale en Java avec la caractéristique supplémentaire qui vous permet d'effectuer une sorte d'héritage multiple c.-à-d. classes qui peuvent être upcast à plus d'une classe.

permet de prendre un exemple simple.

  1. supposons qu'il existe deux classes superclasses A et B avec des noms de méthode identiques mais des fonctionnalités différentes. Par le code suivant avec (étend) mot-clé l'héritage multiple n'est pas possible.

       public class A                               
         {
           void display()
             {
               System.out.println("Hello 'A' ");
             }
         }
    
       public class B                               
          {
            void display()
              {
                System.out.println("Hello 'B' ");
              }
          }
    
      public class C extends A, B    // which is not possible in java
        {
          public static void main(String args[])
            {
              C object = new C();
              object.display();  // Here there is confusion,which display() to call, method from A class or B class
            }
        }
    
  2. mais à travers des interfaces, avec (met en œuvre) l'héritage multiple mot-clé est possible.

    interface A
        {
           // display()
        }
    
    
     interface B
        {
          //display()
        }
    
     class C implements A,B
        {
           //main()
           C object = new C();
           (A)object.display();     // call A's display
    
           (B)object.display(); //call B's display
        }
    }
    
1
répondu Chaitra Deshpande 2015-11-06 16:32:35

en C++, une classe peut hériter (directement ou indirectement) de plus d'une classe, ce qui est appelé l'héritage multiple .

C# et Java, cependant, de limiter les classes à l'héritage simple chaque classe hérite à partir d'une seule classe parent.

l'héritage Multiple est un moyen utile pour créer des classes qui combinent des aspects de deux classes disparates hiérarchies, quelque chose que souvent se produit lorsque l'utilisation de différents cadres de classe dans un seul application.

si deux cadres définissent leurs propres classes de base pour les exceptions, par exemple, vous pouvez utiliser l'héritage multiple pour créer des classes d'exception qui peut être utilisé avec cadre.

le problème avec l'héritage multiple est qu'il peut conduire à l'ambiguïté. L'exemple classique, c'est quand une classe hérite de deux autres classes, dont chacune hérite de la même classe:

class A {
    protected:
    bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
    public:
    void setFlag( bool nflag ){
        flag = nflag; // ambiguous
    }
};

dans cet exemple, le membre de données flag est défini par class A . Mais class D descend de class B et class C , qui dérivent tous deux de A , donc en essence deux copies de flag sont disponibles parce que deux les instances de A sont dans la hiérarchie de classe de D . Lequel voulez-vous mettre? Le compilateur se plaindra que la référence à flag dans D est ambigu . Une solution consiste à désambiguer explicitement la référence:

B::flag = nflag;

un autre correctif est de déclarer B et C comme virtual base classes , ce qui signifie qu'un seul exemplaire d'une can existe dans la hiérarchie, éliminant toute ambiguïté.

Autres complexités existent avec l'héritage multiple, comme l'ordre dans lequel les classes de base sont initialisé lorsqu'un objet dérivé est construit, ou la façon dont les membres peuvent être par inadvertance cachés à partir de classes dérivées. Pour éviter ces complexités, certaines langues se limitent au modèle plus simple de l'héritage unique.

bien que cela simplifie considérablement l'héritage, cela limite également son utilité parce que seules les classes avec un ancêtre commun peuvent partager des comportements. Les Interfaces atténuent ce une certaine restriction en permettant à des classes dans des hiérarchies différentes d'exposer des interfaces communes, même s'ils ne sont pas implémentés par le partage de code.

1
répondu robert 2018-08-19 06:06:34

est-ce que quelqu'un peut me dire précisément pourquoi il n'est pas permis?

vous pouvez trouver réponse à partir de cette documentation lien

une des raisons pour lesquelles le langage de programmation Java ne vous permet pas d'étendre plus d'une classe est d'éviter les problèmes d'héritage multiple de l'état, qui est la capacité d'hériter des champs de classes multiples

Si l'héritage multiple est autorisé et que vous créez un objet en instanciant cette classe, cet objet héritera des champs de toutes les super classes de la classe. Il sera la cause de deux problèmes.

  1. et si des méthodes ou des constructeurs de différentes super classes instanciaient le même champ?

  2. Quelle méthode ou quel constructeur aura préséance?

Even bien que l'héritage multiple de l'état est maintenant autorisé, vous pouvez encore mettre en œuvre

héritage Multiple de type : capacité d'une classe à implémenter plus d'une interface.

succession Multiple de la mise en œuvre (par des méthodes par défaut dans les interfaces) : possibilité d'hériter les définitions de méthode de classes multiples

référez-vous à cette question se liée pour des informations supplémentaires:

l'Héritage Multiple Ambiguïté avec l'Interface

0
répondu Ravindra babu 2017-05-23 12:26:23

imaginez cet exemple: J'ai une classe Shape1

il a CalcualteArea méthode:

Class Shape1
{

 public void CalculateArea()

     {
       //
     }
}

il y a une autre classe Shape2 qui a la même méthode

Class Shape2
{

 public void CalculateArea()

     {

     }
}

maintenant j'ai un cercle de classe d'enfant, il dérive à la fois de la forme 1 et de la forme 2;

public class Circle: Shape1, Shape2
{
}

maintenant quand je crée objet pour cercle, et appelle la méthode, le système ne sait pas qui calcule la méthode de zone à être appelé. Les deux ont les mêmes signatures. Donc le compilateur sera confus. C'est pourquoi les héritages multiples ne sont pas autorisés.

mais il peut y avoir plusieurs interfaces parce que les interfaces n'ont pas de définition de méthode. Même les deux interfaces ont la même méthode, les deux n'ont aucune implémentation et toujours la méthode dans la classe enfant sera exécutée.

-3
répondu Engr Muhammad Enayet Abdullah 2016-11-28 06:12:44