Existe-t-il des langues OO sans héritage?

22

Lors d'une revue de code aujourd'hui, un de mes collègues a dit quelque chose d'intéressant:

prototypen'est utile que lorsque vous avez besoin d'héritage - et quand l'héritage est-il une bonne idée ?

J'y ai pensé et j'ai réalisé que j'utilisais généralement l'héritage pour contourner le code mal conçu au départ. Le style OO moderne préfère la composition à l'héritage, mais je ne connais aucun langage qui ait pris cela à cœur et qui le fasse réellement respecter .

Existe-t-il des langages de programmation à usage général avec des classes, des objets, des méthodes, des interfaces, etc., qui interdisent l'héritage basé sur les classes? (Si une telle idée n'a pas de sens, pourquoi pas?)

Benjamin Hodgson
la source
7
Votre collègue vous a égaré. Le prototypeest également utile lorsque vous disposez de méthodes et de propriétés publiques qui doivent être partagées entre les instances. Il est également utile car il vous permet d'utiliser correctement l' instanceofopérateur en JavaScript: if (foo instanceof Foo) { ....
Greg Burghardt
2
Je pense que nous devrions faire une distinction entre l'héritage de type, l'état et le comportement. La préférence de composition est très courante dans la communauté Java mais en même temps, l'héritage (et même l'héritage multiple) de types est largement utilisé et encouragé ... et réalisé en utilisant le implementsmot - clé et les interfaces (par opposition à l'héritage d'état et comportement introduit avec l'utilisation du extendsmot - clé sur les classes contenant n'importe quelle implémentation).
toniedzwiedz
6
Préférer la composition ne signifie pas abandonner complètement l'héritage est une bonne idée.
Caleb
5
voir Java sans héritage d'implémentation : "Google's go est un exemple de langage qui supprime l'héritage d'implémentation tout en étant OOP ..."
gnat
1
@GregBurghardt La même chose peut être accomplie avec une fonction d'usine qui renvoie un objet contenant des fonctions (stockage de données privées dans la fermeture). new, thiset prototypesont trop d'un champ de mines pour une utilisation courante par l'OMI.
Benjamin Hodgson

Réponses:

18

Laissant de côté la question de la définition de la programmation orientée objet, la question devient «y a-t-il des langages qui n'utilisent que la composition et n'ont pas d'outils pour l'héritage?

La réponse à cette question est tout simplement "oui". En route, il n'y a aucun moyen de faire l'héritage comme on le pense classiquement. On peut incorporer un objet dans un autre objet et étendre cet objet. De Object Desoriented Language ( miroir github ):

type Person struct {
        Name string
}

func (p *Person) Intro() string {
        return p.Name
}

type Woman struct {
        Person
}

func (w *Woman) Intro() string {
        return "Mrs. " + w.Person.Intro()
}

Vous avez une structure de personne qui a un nom qui est une chaîne. Il a une fonction publique appelée Intro qui renvoie le nom. La structure Woman a également une fonction pour Intro qui accède à la jambe de force qui y est intégrée. Et donc on peut réaliser les intentions d'héritage en utilisant uniquement la composition.

Pour en savoir plus, consultez les didacticiels GoLang: héritage et sous-classe dans Go - ou sa quasi-ressemblance .

Alors oui, il est possible d'avoir un langage OO sans héritage, et il en existe un.

Au sein de Go, cela est connu comme l' intégration et donne aux structures englobantes la possibilité d'accéder aux champs et fonctions intégrés comme si elles les avaient également - mais ce n'est pas une sous-classe. La philosophie de conception se trouve dans la FAQ Go: Pourquoi n'y a-t-il pas d'héritage de type?


la source
On pourrait aussi commenter l'utilisation de typedefet structen C ...
cwallenpoole
@cwallenpoole il y a en effet des idées similaires, bien que j'hésite à appeler C un langage orienté objet.
Je ne sais pas. J'admets le fait que vous ne pouvez pas créer d'objets avec des fonctions attachées fonctionne contre cela, mais sans héritage, la POO perd beaucoup de sa saveur.
cwallenpoole
@cwallenpoole et nous commençons à définir ce qu'est l'héritage et l'orientation de l'objet. Mais il est possible, sa juste une façon différente de penser au sujet du problème. Le fait est que l'héritage est la façon dont la plupart des programmeurs C ++ et Java pensent à l'extension ... mais il existe d'autres modèles. Extension sans héritage: 1 , 2 , 3 sont de bonnes lectures.
Le lien vers "Object Desoriented Language" est actuellement bloqué dans une boucle de redirection, mais j'ai trouvé l'article ici: github.com/nu7hatch/areyoufuckingcoding.me/blob/master/content/… . Merci!
Matt Browne du
7

Existe-t-il des langages de programmation à usage général avec des classes, des objets, des méthodes, des interfaces, etc., qui interdisent l'héritage basé sur les classes?

Cela ressemble beaucoup à une description de VBA - Visual Basic pour Applications, intégré à Microsoft Office et à d'autres hôtes compatibles VBA (par exemple AutoCAD, Sage 300 ERP, etc.), ou même VB6. Le "A" de "Basic" signifie "tout usage" de toute façon, il y a donc la partie "polyvalente".

VB6 / VBA a des classes (et donc des objets), des méthodes et des interfaces - vous pouvez définir une ISomethinginterface dans un module de classe comme ceci:

Option Explicit

Public Sub DoSomething()
End Sub

Et puis avoir une autre classe qui fait cela:

Option Explicit
Implements ISomething

Private Sub ISomething_DoSomething()
    'implementation here
End Sub

Une telle classe, n'exposant aucun membre public, ne pourrait être accessible que via son ISomethinginterface - et il pourrait très bien y avoir des dizaines d'implémentations différentes ISomething, donc le code OOP VBA est parfaitement capable de polymorphisme, et il est parfaitement légal pour une classe donnée pour implémenter plusieurs interfaces également.

Cependant, VB6 / VBA n'autorise pas l' héritage de classe , vous ne pouvez donc pas hériter d'une implémentation d'un autre type, uniquement son interface. Maintenant, que ce soit un accident, un défaut de conception, un coup de génie ou une énorme oubli laid est ouvert au débat; il n'est pas clair si VB6 / VBA prend cela à cœur , mais il le fait certainement respecter .

Si Go ne fait pas d'héritage de classe et est néanmoins un langage OOP , alors je ne vois pas pourquoi VB6 / VBA ne pourrait pas être considéré comme un langage OOP.</PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>

Mathieu Guindon
la source
1
Pour être juste, OP a posé des questions sur les langues modernes . =;) -
RubberDuck
@RubberDuck #burn!
Mathieu Guindon
0

Vous pouvez faire en sorte que le compilateur applique l'héritage sélectif grâce à l'utilisation de techniques privées / protégées et grâce à l'utilisation moderne des techniques "PImpl" ou "Private Implementation".

De nombreuses API exposent uniquement les composants dont vous souhaiteriez qu'un utilisateur hérite et masquent le reste dans une classe d'implémentation distincte. Vous pouvez donc écrire des classes dont les interfaces publiques sont, en fait, non héritables, uniquement utilisables via la composition d'objets et appliquées par le compilateur. C'est souvent une bonne pratique, quand il utilise le compilateur pour appliquer l'intention du logiciel.

Une recherche rapide des fonctions des membres privés en javascript montre qu'il existe un principe similaire, bien que tout le monde puisse voir votre code s'il peut l'utiliser: http://www.crockford.com/javascript/private.html

Ruan Caiman
la source