Je suis assez nouveau dans la programmation, mais j'ai lu quelques discussions intéressantes sur StackOverflow sur diverses approches de programmation. Je ne sais toujours pas à 100% quelle est la différence entre la programmation procédurale et la programmation orientée objet. On dirait que la programmation orientée objet utilise toujours des procédures (méthodes) mais tout est organisé différemment car l'objet est la star du spectacle. Mais il me semble que les procédures vous permettent toujours de faire toutes les mêmes choses. Comme en C, vous pouvez mettre toutes vos procédures similaires dans une bibliothèque. Alors, ne pourriez-vous pas vraiment dire qu'une bibliothèque en C est similaire à un objet en C++?
La différence entre les deux est subtile mais significative.
Dans un programme procédural, les modules interagissent en lisant et en écrivant un état stocké dans des structures de données partagées.
Dans un programme orienté objet, les modules sous forme d'objets interagissent en envoyant des messages à d'autres objets.
Dans un programme procédural, le code est roi et les données sont subordonnées. En d'autres termes, vous avez des programmes qui agissent sur les données et ils ne sont généralement pas étroitement liés.
Dans le monde OO, les objets sont la principale chose d'intérêt. Un objet se compose de données et le code qui est autorisé à agir sur ces données, et ils sont très C'est le concept d'encapsulation, la dissimulation d'informations.
Un exemple, disons que vous avez un nombre et que vous voulez le doubler. Une façon procédurale de procéder consiste à:
n = n * 2
Le code ici multiplie assez explicitement n par 2 et stocke le résultat dans n.
La manière OO de faire cela est d'envoyer un "message" à l'objet numérique lui disant de se doubler:
n.double();
L'avantage de cela est appelé polymorphisme. Que se passe-t-il lorsque vous décidez de pouvoir doubler une chaîne comme "bob". Dans le monde procédural, vous devrez fournir plus de code pour effectuer le doublage, mais vous devrez également appeler ce code différemment.
Avec OO, vous créez un objet chaîne qui peut également recevoir le message "double". Le code pour doubler une chaîne appartient à l'objet chaîne, il sait donc qu'il doit agir différemment de l'objet numérique. S'il décidait que "bob" * 2 était "bobbob", le code ressemblerait à quelque chose comme:
class number: class string:
int n char array s
procedure double: procedure double:
n = n * 2 s = string_join(s,s)
Ensuite, vous pouvez appeler x.double () quel que soit le type réel x (nombre ou chaîne) et il saura quel code exécuter - cela simplifie considérablement votre code. Vous pouvez doubler des nombres entiers, des chaînes, des matrices, des nombres complexes, des réels, des tailles de fenêtres sur votre moniteur et toutes sortes de choses différentes.
Et vous avez raison, une bibliothèque C peut être conçue pour ressembler un peu à des objets. L'exemple classique est stdio.h
- vous ne vous souciez jamais quoi un FILE*
Pointe en fait, juste le fait qu'il se comportera d'une certaine manière. FILE*
, fopen()
, fclose()
et d'autres fonctions sont une classe de sortes représentant les capacités d'E/S de C.
Vous pouvez programmer de manière procédurale dans la plupart des langues OO, mais la puissance de OO vient de la capacité d'hériter, d'encapsuler et d'abstraire cette logique procédurale. Je pense que vous êtes correct, une bibliothèque devrait ressembler beaucoup à une classe. Elle devrait avoir sa propre portée et encapsuler la logique derrière les fonctions avec des noms significatifs.
Vous avez raison de dire que les programmes orientés objet sont basés à bien des égards sur le paradigme procédural. Vous avez également raison en ce que tout ce qui se passe syntaxiquement, c'est que vous appelez des fonctions. En fait, vous pouvez implémenter de nombreuses fonctionnalités des langages orientés objet à l'aide de mécanismes procéduraux (par exemple, les pointeurs de fonction en C++). Vous pouvez donc faire une conception orientée objet et toujours l'implémenter dans un langage procédural (par exemple, comme le faisaient les anciens compilateurs C++).
L'importance du paradigme orienté objet n'est pas autant dans le mécanisme du langage que dans le processus de réflexion et de conception. Dans la programmation procédurale, la réflexion porte sur les opérations et leur décomposition en utilisant d'autres opérations, en les regroupant en modules, etc. Cela signifie que les données ou l'état ont une importance secondaire. C'est comme penser aux opérations mathématiques.
Le paradigme orienté objet, d'autre part, dit que vous devez considérer l'état et les opérations ensemble comme une entité, puis concevoir votre programme comme des interactions entre des entités qui échangent des états et activent des opérations.
À mon humble avis, la programmation orientée objet est un concept qui existe à un niveau d'abstraction plus élevé que la programmation procédurale. Les deux ne s'excluent pas mutuellement dans la mesure où les méthodes individuelles d'un programme OO ressemblent à peu près aux fonctions individuelles d'un programme procédural. Cela contraste, par exemple, avec la programmation fonctionnelle, qui nécessite une En outre, vous pouvez écrire de manière procédurale dans un langage OO en rendant tout statique, etc. Vous pouvez être un compilateur humain et écrire efficacement OO code dans C en utilisant beaucoup de pointeurs de fonction et de transtypage de pointeur struct.
OO est donc davantage une philosophie de conception et une vision du monde que quelque chose avec une définition rigoureuse. Cela nécessite que l'héritage, le polymorphisme, etc. soient utilisés comme modèles majeurs dans la structuration de votre code, et que la syntaxe soit fournie pour les rendre exprimables sans recourir à des astuces de bas niveau. Cela nécessite que vous pensiez au code qui agit sur l'état d'une collection de données comme étant une propriété des données, pas une procédure qui existe par elle-même. Ce n'est pas noir et blanc. Votre code peut être "plus" ou "moins" OO selon la façon dont vous comptez sur l'héritage, le polymorphisme, les classes et les "méthodes comme propriété des données" vision du monde comme moyen de structurer et expliquer/comprendre votre code.
OO est surtout un état d'esprit. Vous pouvez programmer OO en C (si vous voulez vraiment ...), et vous pouvez parfaitement avoir du code procédural en C++/Java; ce que je veux dire, même si vous utilisez des classes sur le surface, il pourrait encore être procédural.
L'idée derrière OO est l'abstraction de l'état. Au lieu de "penser" en termes de "groupements de données", vous "pensez" en termes d '"objets", où un objet est une "interface" "pour" le regroupement des données et les moyens de manipuler ces données ".
Tout cela semble philosophique, car ça l'est.
Il y a beaucoup à dire ici, et tout ne peut pas être dit dans un petit SO post, donc je vais le laisser ici.
[~ # ~] mise à jour [~ # ~]
Comme mentionné dans réponse de Flanagan , OO les langages implémentent des constructions qui utilisent cette abstraction.
Je veux dire, vous pourriez techniquement "pirater" les classes et le polymorphisme en termes de structures, de fonctions et de pointeurs de fonctions.
Voici un exemple de OO en C
La différence est que les objets ont des procédures et des données associées au même endroit - les langages procéduraux utilisent des "structures" (des choses qui maintiennent les données liées ensemble) qui maintiennent les données séparées des procédures. En effet, tout ce que vous faites dans un langage OO devrait être possible dans un langage procédural avec une combinaison de structures et de procédures.
La principale différence est l'état d'esprit dans lequel une langue OO place les programmeurs.
[pardonnez le style d'apprêt, il est tard et je suis fatigué]
les procédures traitent les données - les données entrent, appliquent un certain traitement, sortent les données
parfois, certains des éléments de données sont liés à certains des autres éléments de données, et il est pratique de les regrouper dans un structure de données, qui peut ensuite être manipulé et adressé comme une seule unité.
maintenant notre procédure peut prendre une structure de données en entrée et la modifier et/ou produire une autre structure de données en sortie
nous constatons parfois que certaines procédures ne concernent qu'un certain type de structure de données; il est commode de regrouper ces procédures avec leur structure de données, et de l'appeler un objet.
un modèle pour créer des objets est appelé classe; un objet est dit instance d'une classe
nous pouvons remarquer qu'une classe ressemble beaucoup à une autre, donc au lieu de copier et coller du code, nous laissons une classe hériter d'une autre: la sous-classe hérite de la superclasse ou "classe de base". De cette façon, la sous-classe a accès à toutes les structures de données et procédures de la superclasse, et peut les augmenter ou les remplacer de certaines manières
si nous demandons poliment à un objet de faire quelque chose pour nous au lieu d'appeler brutalement ses procédures directement, cela s'appelle passage de message, même si aucun "message" réel n'est transmis. La joie ici est que de nombreux types d'objets différents peuvent comprendre le même message, ce qui conduit à la notion de polymorphisme. Par exemple, nous pouvons demander à différents types de documents de s'imprimer eux-mêmes, et chacun répond de manière appropriée.
un langage qui prend en charge les objets (via des classes ou non) avec passage de message et héritage est appelé orienté objet. S'il n'y a pas d'héritage, le langage est simplement basé sur les objets.
bonne chance avec vos études!
La procédure fait partie de la distinction procédurale/fonctionnelle/logique (ou orientée logique) (comparer c, LISP et prolog) entre différentes façons de décrire ce qu'un programme doit faire.
L'orientation des objets est orthogonale à cette autre idée et décrit un moyen de regrouper des sous-programmes avec des données. C++ et Java sont des langages procéduraux avec des fonctionnalités orientées objet; fortran77 est un langage procédural sans fonctionnalités orientées objet. LISP commun prend en charge l'orientation objet; certains lisps plus anciens ne le font pas. Le prologue Plain Vanilla ne prend pas en charge les objets, et je ne peux pas nommer un langage orienté logique qui le fasse (je ne fais pas de programmation orientée logique, c'est sur ma liste de choses à faire quand je ai un peu de temps libre copieux. Je fais à peine fonctionnel programmation).
Comme d'autres l'ont remarqué, cependant, une réflexion orientée objet appropriée change la façon dont vous faites votre programmation autant qu'un passage de procédural à fonctionnel.
BTW - Je vois que "procédural" est beaucoup utilisé pour distinguer les langages procéduraux non orientés objet de leurs frères orientés objet, mais je pense que c'est une mauvaise utilisation motivée par l'absence d'adjectif propre pour "non orienté objet". YMMV.
Dans un programme procédural, vous divisez un gros problème en petits problèmes et résumez chacun de ces petits problèmes en tant que procédure. C'est ce qu'on appelle l'abstraction procédurale.
Dans les programmes orientés objet, vous analysez un problème comme certains objets et l'interaction entre les objets. C'est ce qu'on appelle l'abstraction d'objet.
Son plus facile à comprendre dans le contexte, regardez d'autres abstractions introduites entre les langues.
Une différence clé entre le langage Assembly et un langage procédural comme C ou Pascal est l'introduction de l'abstraction "procedure". Les personnes qui écrivent du code d'assemblage créent des procédures, mais son langage dur et sujet aux erreurs, un langage procédural vous donne des outils pour le rendre plus facile.
La différence entre un langage procédural et un OO langage comme C++ est l'abstraction "objet". Les personnes qui écrivent "c" créent souvent des objets conceptuels mais c'est difficile et sujet aux erreurs =, une langue OO vous donne des outils pour vous faciliter la tâche.
Des choses comme Sing # de Microsoft (ou Erlang) ajoutent l'abstraction Message/Process dans la langue. Bien sûr, vous pouvez faire passer des messages et créer des processus dans Assembly, C ou C++ mais Sing # facilite les choses.
Tout se résume au même code machine, ces abstractions sont purement au profit de notre cerveau, pas de l'ordinateur.
La différence est
Programmation orientée procédures - Donne de l'importance à l'algorithme plutôt qu'aux données.Cette méthode de programmation se concentre sur les procédures, c'est-à-dire les méthodes pour effectuer une tâche spécifique et partager leur structure de données. Il suit des structures descendantes.
exemple: Pascal et C
Programmation orientée objet - Donne de l'importance aux données plutôt qu'à l'algorithme. Il suit des structures ascendantes, chaque chose est considérée comme un objet. Chaque objet a sa propre structure de données et sa propre procédure. Il comprend des fonctionnalités telles que le masquage de données, le polymorphisme, l'encapsulation et la transmission de messages. Les utilisateurs n'ont vraiment pas à se soucier de ce qui se trouve à l'intérieur de ces objets, tout en les utilisant dans leurs programmes.
exemple: C++ et Java
Ceci est une réponse simplifiée.
Dans un vrai langage OO, le seul codage procédural se fait à l'intérieur d'un objet.
C n'a pas d'objets et C++ est un langage qui prend en charge les objets. Java par contre tout est un objet (sauf les primitives). Tout est tapé.
Cela dépend de la façon dont vous définissez la POO. En termes de Java OOP où vous appelez des méthodes sur des objets, la programmation procédurale est à peu près la même. Pour autant que je sache, vous pouvez émuler tout OOP = principes (encapsulation, abstraction, polymorphisme, héritage) dans un langage procédural comme C. La preuve en est GObject , dans une certaine mesure Objective-C, et bien d'autres OOP = implémentations de langage utilisant C, comme cPython. Cela se fait en utilisant des structures et en opérant sur ces structures en utilisant des fonctions:
typedef struct {
Object *isa;
String *name;
Date *birthday;
} Person;
Person *Person_new();
String *Person_name(Person *self);
void Person_setName(Person *self, String *newName);
// ...
L'interface est très OOP comme. Elle ne permet pas vraiment le polymorphisme, mais c'est aussi possible. Elle est très similaire à une interface Python, sauf que les attributs sont distincts des "méthodes":
class Person(object):
def __init__(self):
self._name = ""
self._age = datetime.datetime.now()
@property
def name(self):
return self._name
@property
def age(self):
return self._age
J'ai choisi Python pour l'exemple parce que "self" est explicite, comme dans l'exemple C. De nombreux langages OOP, comme Java, font abstraction).
Il y a aussi le Smalltalk-like OOP où les messages sont envoyés aux objets, plutôt que d'appeler des méthodes sur des objets. La différence est subtile à première vue, mais elle offre beaucoup de puissance et de flexibilité. peut également être implémenté dans des langages procéduraux, comme le prouve Objective-C.
La programmation orientée objet n'est pas nécessairement un type de langage, mais plutôt un paradigme. Les langages orientés objet tels que Java, Python, Ruby, etc., fournissent du sucre syntaxique pour manipuler facilement les objets, et c'est la principale différence entre les "langages procéduraux" et les "langages orientés objet".
En effet, une bibliothèque, ou plutôt un ensemble de fonctions opérant sur une structure, est la même chose qu'un objet en C++. En fait, C++ est implémenté de cette façon.
Beaucoup de points intéressants déjà mentionnés ici.
Une façon d'y penser est qu'en OO, vous avez l'idée des "objets" qui sont des choses qui ont des caractéristiques et des comportements qui leur sont inhérents. Ils ont généralement une sorte d '"interface" publique qui fournit un mécanisme pour récupérer des informations à leur sujet, mais l'objet lui-même, ou plutôt sa "classe", limite les informations accessibles au public. Les entrailles de l'objet ne sont pas exposées au public car il n'est généralement pas nécessaire de connaître les détails sales "sous le capot" de l'objet. Les programmes orientés objet utilisent donc cette construction, ainsi que d'autres choses.
La programmation procédurale n'utilise généralement pas un tel couplage de données et de comportement dans un "objet". Je l'ai déjà vu en C, mais ce n'était pas joli et impliquait beaucoup trop de travail de singe pour approximer ce que l'on pouvait faire avec, par exemple, C++.
L'une des idées derrière le développement orienté objet est que je ne devrais pas pouvoir fouiller avec vos données par d'autres moyens que ceux que vous avez fournis. Si vous ne me fournissez qu'une interface bien pensée, vous pouvez me garder honnête. Maintenant, si vous utilisez une approche procédurale et que vous m'envoyez une structure qui n'a pas de protections intégrées, eh bien je peux faire ce que je veux et si je suis stupide ou mauvais, je peux changer des choses que vous ne voudriez peut-être pas que je fasse changement.
Certes, vous pouvez contourner l'objet si vous êtes intelligent, mais vous devez vous mettre en quatre pour le faire.
Ce n'est pas complet, mais c'est un aspect.
La façon dont C++ est implémenté fait que la programmation OO ressemble beaucoup à la programmation procédurale. Vous devez légèrement changer votre façon de penser.
En C++, les objets ont des méthodes qui ne sont que des procédures qui agissent sur l'objet. Mais dans un vrai OO paradiam vous devriez considérer les méthodes comme des messages potentiels que l’objet peut recevoir (c.-à-d. Des lettres). L’objet reçoit un message (les paramètres représentent la charge utile du message c.-à-d. contenu de la lettre) et change son état en fonction du message.
Pour un exemple assez direct de la différence entre la procédure et l'OO, essayez d'apprendre Smalltalk. Dans Smalltalk, tout, et je veux dire que tout est un objet. Il n'y a pas d'instructions if ni de boucles while. Vous obtenez cette fonctionnalité en envoyant des messages à (alias invoquant des méthodes sur) d'autres objets. Cela fait vraiment tourner la tête au début, mais je pense que vous allez rapidement comprendre ce que OO est censé être.