Je sais que l'héritage multiple n'est pas autorisé en Java et C #. De nombreux livres disent simplement que l'héritage multiple n'est pas autorisé. Mais il peut être implémenté en utilisant des interfaces. Rien n'est discuté sur les raisons pour lesquelles cela n'est pas autorisé. Quelqu'un peut-il me dire précisément pourquoi ce n'est pas autorisé?
c#
java
language-design
multiple-inheritance
Abdulsattar Mohammed
la source
la source
Réponses:
La réponse courte est: parce que les concepteurs de langage ont décidé de ne pas le faire.
Fondamentalement, il semblait que les concepteurs .NET et Java n'autorisaient pas l'héritage multiple car ils pensaient que l'ajout de MI ajoutait trop de complexité aux langages tout en offrant trop peu d'avantages .
Pour une lecture plus ludique et approfondie, il y a quelques articles disponibles sur le web avec des interviews de certains des designers de langage. Par exemple, pour .NET, Chris Brumme (qui a travaillé chez MS sur le CLR) a expliqué les raisons pour lesquelles ils ont décidé de ne pas:
Vous pouvez lire l'article entier ici.
Pour Java, vous pouvez lire cet article :
la source
L'héritage multiple de l' implémentation est ce qui n'est pas autorisé.
Le problème est que le compilateur / runtime ne peut pas déterminer quoi faire si vous avez une classe Cowboy et une classe Artist, toutes deux avec des implémentations pour la méthode draw (), et que vous essayez ensuite de créer un nouveau type CowboyArtist. Que se passe-t-il lorsque vous appelez la méthode draw ()? Quelqu'un est-il mort dans la rue ou avez-vous une belle aquarelle?
Je crois que cela s'appelle le problème de l'héritage du double diamant.
la source
Raison: Java est très populaire et facile à coder, en raison de sa simplicité.
Donc, quoi que les développeurs Java se sentent difficile et compliqué à comprendre pour les programmeurs, ils ont essayé de l'éviter. Un tel type de propriété est l'héritage multiple.
Problème d'héritage multiple: problème de diamant.
Exemple :
Telle est l'ambiguïté qui existe dans le problème des diamants.
Il n'est pas impossible de résoudre ce problème, mais cela crée plus de confusion et de complexité pour le programmeur lors de sa lecture. Cela cause plus de problèmes qu'il ne tente de résoudre.
Remarque : De toute façon, vous pouvez toujours implémenter indirectement l'héritage multiple en utilisant des interfaces.
la source
Parce que Java a une philosophie de conception très différente de C ++. (Je ne vais pas discuter de C # ici.)
Lors de la conception du C ++, Stroustrup souhaitait inclure des fonctionnalités utiles, quelle que soit la manière dont elles pourraient être mal utilisées. Il est possible de se tromper avec l'héritage multiple, la surcharge d'opérateurs, les modèles 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 mettre 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 délicates à faire, mais vous pouvez être beaucoup plus sûr que le code que vous regardez signifie ce que vous pensez qu'il fait.
De plus, Java était dans une large mesure une réaction de C ++ et Smalltalk, les langages OO les plus connus. Il existe de nombreux autres langages OO (Common Lisp était en fait le premier à être normalisé), avec différents systèmes OO qui gèrent mieux MI.
Sans oublier qu'il est tout à fait possible de faire du MI en Java, en utilisant les interfaces, la composition et la délégation. C'est plus explicite qu'en C ++, et donc plus maladroit à utiliser, mais vous apportera quelque chose que vous êtes plus susceptible de comprendre à première vue.
Il n'y a pas de bonne réponse ici. Il existe différentes réponses, et celle qui est la meilleure pour une situation donnée dépend des applications et des préférences individuelles.
la source
La principale (bien que ce ne soit pas la seule) raison pour laquelle les gens s'éloignent de l'IM est le soi-disant «problème du diamant» qui conduit à une ambiguïté dans votre mise en œuvre. Cet article de wikipedia en parle et explique mieux que je ne pourrais. MI peut également conduire à un code plus complexe, et de nombreux concepteurs OO affirment 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.
la source
En C ++, l'héritage multiple était un casse-tête majeur lorsqu'il était mal utilisé. Pour éviter ces problèmes de conception courants, l '«héritage» de plusieurs interfaces a été forcé à la place dans les langues modernes (java, C #).
la source
L'héritage multiple est
Par conséquent, il peut être considéré comme un choix judicieux de ne pas inclure l'héritage multiple dans le langage Java.
la source
Une autre raison est que l'héritage unique rend la conversion triviale, n'émettant aucune instruction d'assembleur (autre que la vérification de la compatibilité des types si nécessaire). Si vous avez un héritage multiple, vous devez déterminer où commence un certain parent dans la classe enfant. La performance est donc certainement un avantage (mais pas le seul).
la source
Dans le passé (années 70), lorsque l'informatique était plus scientifique et moins production de masse, les programmeurs avaient le temps de réfléchir à une bonne conception et une bonne mise en œuvre et, par conséquent, les produits (programmes) étaient de haute qualité (par exemple, conception TCP / IP et mise en œuvre). De nos jours, quand tout le monde programme et que les gestionnaires changent les spécifications avant les dates limites, des problèmes subtils comme celui décrit dans le lien wikipedia du post de Steve Haigh sont difficiles à suivre; par conséquent, "l'héritage multiple" est limité par la conception du compilateur. Si vous l'aimez, vous pouvez toujours utiliser C ++ ... et avoir toute la liberté que vous voulez :)
la source
Je prends la déclaration 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 comme types car elles ont un comportement. Java a donc un héritage multiple. Juste que c'est plus sûr.
la source
Le chargement dynamique des classes rend difficile l'implémentation de l'héritage multiple.
En java, ils ont en fait évité la complexité de l'héritage multiple à la place en utilisant un héritage et une interface uniques. La complexité de l'héritage multiple est très élevée dans une situation comme expliqué ci-dessous
problème de diamant de l'héritage multiple. Nous avons deux classes B et C héritées de A. Supposons que B et C surchargent une méthode héritée et fournissent leur propre implémentation. Désormais, D hérite à la fois de B et de C faisant l'héritage multiple. D devrait hériter de cette méthode remplacée, jvm ne peut pas décider quelle méthode remplacée sera utilisée?
En 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 instanciées - elles ne peuvent être implémentées que par des classes ou étendues par d'autres interfaces.
la source
En fait, l'héritage multiple se produira à la complexité si les classes héritées ont la même fonction. c'est-à-dire que le compilateur aura une confusion que l'on doit choisir (problème de diamant). Donc, en Java, cette complexité a été supprimée et a donné une interface pour obtenir les fonctionnalités telles que l'héritage multiple. Nous pouvons utiliser l'interface
la source
Java a un concept, c'est-à-dire un polymorphisme. Il existe 2 types de polymorphisme en java. Il existe une surcharge de méthode et un remplacement de méthode. Parmi eux, le remplacement de méthode se produit avec une relation de super-classe et 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 étend plus d'une classe, quelle méthode de super-classe doit être appelée?
Ou, en appelant le constructeur de superclasse par
super()
, quel constructeur de superclasse sera appelé?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.
la source
L'héritage multiple n'est pas autorisé directement dans Java, mais via les interfaces, il est autorisé.
Raison:
Héritage multiple: introduit plus de complexité et d'ambiguïté.
Interfaces: les interfaces sont des classes complètement abstraites en Java qui vous offrent un moyen uniforme de délimiter correctement 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 meilleur contrôle. sur la façon dont vous créez et interagissez avec d’autres classes.
Plus précisément, il s'agit d'une construction spéciale en Java avec la caractéristique supplémentaire qui vous permet d'effectuer une sorte d'héritage multiple, c'est-à-dire des classes qui peuvent être remontées vers plus d'une classe.
Prenons un exemple simple.
Supposons qu'il existe 2 classes de superclasses A et B avec les mêmes noms de méthode mais des fonctionnalités différentes. Grâce au code suivant avec le mot clé (extend), l'héritage multiple n'est pas possible.
Mais grâce aux interfaces, avec (implémente) l'héritage multiple de mots-clés est possible.
la source
Vous pouvez trouver la réponse à partir de ce lien de documentation
Si l'héritage multiple est autorisé et lorsque vous créez un objet en instanciant cette classe, cet objet héritera des champs de toutes les super classes de la classe. Cela causera deux problèmes.
Et si des méthodes ou des constructeurs de différentes super classes instanciaient le même champ?
Quelle méthode ou quel constructeur aura la priorité?
Même si l'héritage multiple d'état est désormais autorisé, vous pouvez toujours implémenter
Héritage multiple de type : capacité d'une classe à implémenter plus d'une interface.
Héritage multiple de l'implémentation (via les méthodes par défaut dans les interfaces): possibilité d'hériter des définitions de méthode de plusieurs classes
Reportez-vous à cette question SE connexe pour plus d'informations:
Ambiguïté d'héritage multiple avec interface
la source
En C ++, une classe peut hériter (directement ou indirectement) de plusieurs classes, ce que l'on appelle l' héritage multiple .
Cependant, C # et Java limitent les classes à un seul héritage, chaque classe hérite d'une seule classe parente.
L'héritage multiple est un moyen utile de créer des classes qui combinent des aspects de deux hiérarchies de classes disparates, ce qui se produit souvent lors de l'utilisation de différents frameworks de classes dans une seule application.
Si deux frameworks 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'exceptions qui peuvent être utilisées avec l'un ou l'autre framework.
Le problème de l'héritage multiple est qu'il peut conduire à une ambiguïté. L'exemple classique est lorsqu'une classe hérite de deux autres classes, dont chacune hérite de la même classe:
Dans cet exemple, le
flag
membre de données est défini parclass A
. Maisclass D
descend declass B
etclass C
, qui dérivent tous deux deA
, donc, en substance, deux copies deflag
sont disponibles parce que deux instances deA
sont dansD
la hiérarchie de classes de. Lequel souhaitez-vous définir? Le compilateur se plaindra que la référence àflag
dansD
est ambiguë . Un correctif consiste à clarifier explicitement la référence:Un autre correctif consiste à déclarer B et C comme
virtual base classes
, ce qui signifie qu'une seule copie de A peut exister dans la hiérarchie, éliminant toute ambiguïté.D'autres complexités existent avec l'héritage multiple, telles que l'ordre dans lequel les classes de base sont initialisées lorsqu'un objet dérivé est construit, ou la façon dont les membres peuvent être masqués par inadvertance des classes dérivées. Pour éviter ces complexités, certains langages se limitent au modèle d'héritage unique plus simple.
Bien que cela simplifie considérablement l'héritage, cela limite également son utilité car seules les classes avec un ancêtre commun peuvent partager des comportements. Les interfaces atténuent quelque peu cette restriction en permettant aux classes de différentes hiérarchies d'exposer des interfaces communes même si elles ne sont pas implémentées en partageant du code.
la source
Imaginez cet exemple: j'ai une classe
Shape1
Il a la
CalcualteArea
méthode:Il y a une autre classe
Shape2
que l'on a aussi la même méthodeMaintenant, j'ai une classe enfant Circle, elle dérive à la fois de Shape1 et Shape2;
Maintenant, lorsque je crée un objet pour Circle et que j'appelle la méthode, le système ne sait pas quelle méthode de calcul de la surface doit être appelée. 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 car 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 de la classe enfant sera exécutée.
la source