Je pense que C est parfaitement correct et décent pour la mise en œuvre de concepts orientés objet, haussement d'épaules . La plupart des différences que je vois entre le sous-ensemble de dénominateurs communs de langages considérés comme orientés objet sont mineures et de nature syntaxique, de mon point de vue pragmatique.
Commençons par, disons, la dissimulation d'informations. En C, nous pouvons y parvenir simplement en cachant la définition d’une structure et en l’utilisant avec des pointeurs opaques. Que efficacement les modèles de la public
contre private
distinction des champs de données que nous obtenons des classes. Et il est assez facile à faire et à peine anti-idiomatique, car la bibliothèque C standard repose énormément sur cela pour dissimuler des informations.
Bien sûr, vous perdez la possibilité de contrôler facilement où la structure est allouée en mémoire en utilisant des types opaques, mais ce n'est qu'une différence notable entre, par exemple, C et C ++. Le C ++ est certainement un outil supérieur pour comparer sa capacité à programmer des concepts orientés objet sur C tout en maintenant le contrôle sur les dispositions de mémoire, mais cela ne signifie pas nécessairement que Java ou C # est supérieur à C à cet égard, car ces deux perdre complètement la capacité de contrôler où les objets sont alloués en mémoire.
Et nous devons utiliser une syntaxe similaire fopen(file, ...); fclose(file);
à opposée à file.open(...); file.close();
mais big whoop. Qui se soucie vraiment? Peut-être juste quelqu'un qui mise beaucoup sur l'auto-complétion dans son IDE. Je reconnais que cela peut être une fonctionnalité très utile d’un point de vue pratique, mais peut-être pas une qui nécessite une discussion sur le point de savoir si une langue est adaptée à la programmation orientée objet.
Nous n'avons pas la capacité de mettre en œuvre efficacement les protected
champs. Je vais totalement soumettre là. Mais je ne pense pas qu'il y ait de règle concrète qui dit: " Tous les langages OO devraient avoir une fonctionnalité permettant aux sous-classes d'accéder aux membres d'une classe de base auxquels les clients normaux ne devraient toujours pas accéder ." En outre, je vois rarement des cas d'utilisation pour des membres protégés qui ne craignent pas au moins de devenir un obstacle à la maintenance.
Et bien sûr, nous devons "émuler" le polymorphisme OO avec des tables de pointeurs de fonction et des pointeurs vers ceux-ci pour un envoi dynamique avec un peu plus de passe-partout pour initialiser ces analogiques vtables
et vptrs
, mais un peu de passe-passe ne m'a jamais causé beaucoup de chagrin.
L'héritage est à peu près la même chose. Nous pouvons facilement modéliser cela par la composition et, dans les rouages internes des compilateurs, cela revient au même. Bien sûr, nous perdons la sécurité de type si nous voulons baisser le ton , et là, je dirais que si vous voulez être discret , il vous suffit de ne pas utiliser C pour cela, car ce que les gens font en C pour imiter le downcast peut être horrible d'un type sécurité, mais je préférerais que les gens ne soient pas abattus du tout. La sécurité de type est quelque chose que vous pouvez facilement commencer à manquer en C, car le compilateur offre une marge de manœuvre suffisante pour interpréter les choses sous forme de bits et d'octets, sacrifiant ainsi la possibilité de détecter les erreurs qui pourraient se produire au moment de la compilation, mais certains langages étaient considérés comme orientés objet. même pas statiquement tapé.
Donc, non, je pense que ça va. Bien sûr, je n’utiliserais pas C pour essayer de créer une base de code à grande échelle conforme aux principes de SOLID, mais cela n’est pas nécessairement dû à ses défauts dans le domaine orienté objet. Un grand nombre des fonctionnalités qui me manqueraient si j'essayais d'utiliser C à cette fin sont liées à des fonctionnalités de langage qui ne sont pas directement considérées comme une condition préalable à la POO, telles que la sécurité de type forte, les destructeurs qui sont automatiquement appelés lorsque des objets sortent de la portée, l'opérateur surcharge, modèles / génériques et traitement des exceptions. C'est quand je manque ces fonctionnalités auxiliaires que j'atteins pour C ++.