В чем разница между процедурной программой и объектно-ориентированной программой? [закрытый]
Я довольно новичок в программировании, но я читал некоторые интересные дискуссии о StackOverflow о различных подходах к программированию. Я все еще не на 100% понимаю, в чем разница между процедурным и объектно-ориентированным программированием. Похоже, объектно-ориентированное программирование все еще использует процедуры (методы), но все организовано по-другому, потому что объект является звездой шоу. Но мне кажется, что процедуры все-таки позволяют делать все то же самое вещи. Как и в C, вы можете поместить все свои аналогичные процедуры в библиотеку. Не могли бы вы сказать, что библиотека в C похожа на объект в C++?
17 ответов
разница между ними тонкая, но существенная.
в процедурной программе модули взаимодействуют путем чтения и записи состояния, которое хранится в общих структурах данных.
в объектно-ориентированной программе модули в виде объектов взаимодействуют путем отправки сообщений другим объектам.
в процедурной программе Код является королем, а данные-подчиненными. Другими словами, у вас есть программы, которые действуют на данные, и они обычно не связаны.
в мире ОО объекты-это основная вещь, представляющая интерес. Объект состоит из данных и код, который разрешено действовать на этих данных, и они очень тесно связаны. Это концепция инкапсуляции, сокрытия информации.
пример, Допустим, у вас есть ряд и ты хочешь удвоить его. Процедурный способ сделать это:
n = n * 2
код здесь явно умножает n на 2 и сохраняет результат обратно в n.
способ OO сделать это-отправить" сообщение " объекту number, сообщая ему удвоить себя:
n.double();
преимущество этого называется полиморфизмом. Что происходит, когда вы решаете, что хотите иметь возможность удвоить строку, такую как "Боб". В процедурном мире вам придется предоставить больше кода чтобы выполнить удвоение, но вам также придется называть этот код по-другому.
С помощью OO вы создаете строковый объект, который также может принимать сообщение "double". Код для удвоения строки принадлежит объекту string, поэтому он знает, что он должен действовать по-разному с объектом number. Если бы он решил, что " bob "* 2 был "bobbob", код выглядел бы примерно так:
class number: class string:
int n char array s
procedure double: procedure double:
n = n * 2 s = string_join(s,s)
тогда вы можете позвонить x.double () независимо от того, какой фактический тип x был (номер или строка) , и он будет знать, какой код для запуска - это значительно упрощает ваш код. Вы можете удвоить целое число, строки, матрицы, комплексные числа, реалы, размеры окон на вашем мониторе и всевозможные разные вещи.
и вы правы, библиотеку C можно сделать немного похожей на объекты. Классический пример stdio.h
- ты никогда не заботишься что a FILE*
на самом деле указывает только на то, что он будет вести себя определенным образом. The FILE*
, fopen()
, fclose()
и другие функции класс сортов, представляющих возможности ввода/вывода в с.
вы можете программировать процедурно на большинстве языков OO, но сила OO исходит из способности наследовать, инкапсулировать и абстрагировать эту процедурную логику. Я думаю, вы правы, библиотека должна выглядеть как класс. Он должен иметь свою собственную область и инкапсулировать логику за функциями со значимыми именами.
вы правы в своем наблюдении, что объектно-ориентированные программы, основанные во многом на процедурной парадигме. Вы также правы в том, что синтаксически все, что действительно происходит, - это вызов функций. Фактически, вы можете реализовать многие функции объектно-ориентированных языков, используя процедурные механизмы (например, указатели функций в C++). Таким образом, вы можете сделать объектно-ориентированный дизайн и реализовать его на процедурном языке (например, как это делали старые компиляторы C++).
важность объектно-ориентированной парадигмы не столько в языковом механизме, сколько в процессе мышления и проектирования. В процедурном программировании речь идет об операциях и разбиении этих операций на другие операции, группировании их в модули и т. д. Это означает, что данные или состояние имеют второстепенное значение. Это как думать о математических операциях.
объектно-ориентированная парадигма, с другой стороны hand, говорит, что вам нужно думать о состоянии и операциях вместе как о сущности, а затем разработать свою программу как взаимодействия между сущностями, которые обмениваются состоянием и активируют операции.
ИМХО, объектно-ориентированное программирование-это концепция, которая существует на более высоком уровне абстракции, чем процедурное программирование. Эти два не являются взаимоисключающими в том, что отдельные методы в программе OO выглядят почти так же, как отдельные функции в процедурной программе. Это контрастирует, например, с функциональным программированием, которое требует совершенно другого мышления. Кроме того, вы можете писать процедурно на языке OO, делая все статичным и т. д. Вы можете быть человеческий компилятор и эффективно писать OO-код в C, используя множество указателей функций и литье указателей структуры.
ОО, тогда, больше философии дизайна и мировоззрения, чем что-то с строгим определением. Это требует наследования, полиморфизма и т. д. используйте в качестве основных шаблонов при структурировании кода, и этот синтаксис будет предоставлен, чтобы сделать их выразимыми, не прибегая к трюкам низкого уровня. Это требует, чтобы вы подумали о коде, который действует на состояние коллекции данных как свойства данных, а не процедуры, которая существует сама по себе. Она не черно-белая. Ваш код может быть "больше" или "меньше" OO в зависимости от того, насколько сильно вы полагаетесь на наследование, полиморфизм, классы и мировоззрение "методы как свойство данных" как средство структурирования и объяснения/понимания вашего кода.
ОО-это в основном установка ума. Вы можете запрограммировать OO на C (если вы действительно хотите ... ), и вы можете отлично иметь процедурный код на C++ / Java; я имею в виду, что даже если вы используете классы на поверхности, это все равно может быть процедурным.
идея, стоящая за ОО, - это абстракция состояния. Вместо " мышления "в терминах" группировки данных "вы" думаете "в терминах" объектов", где объект является" интерфейсом "для"группировки данных и способов манипулирования этими данными".
все звучит философски, потому что это.
здесь есть что сказать, и это не может быть все сказано в маленьком so post, поэтому я оставлю его здесь.
обновление
Как упоминалось в ответ Фланагана, OO языки реализуют конструкции, которые используют эту абстракцию.
Я имею в виду, что вы можете технически "взломать" классы и полиморфизм с точки зрения структур, функций и указателей функций.
вот пример OO в C
разница в том, что объекты имеют процедуры и связанные данные в одном и том же месте - процедурные языки используют "структуры" (вещи, которые держат связанные данные вместе), которые держат данные отдельно от процедур. Фактически все, что вы делаете на языке OO, должно быть возможно на процедурном языке с комбинацией структур и процедур.
основное различие-это набор ума, в который языки OO помещают программистов.
[извините за стиль праймера, уже поздно, и я устал]
процедуры обработки данных-данные в, применить некоторую обработку, получить данные из
иногда некоторые элементы данных связаны с некоторыми другими элементами данных, и удобно группировать их вместе в структуры данных, который затем можно манипулировать и рассматривать как одну единицу.
теперь наша процедура может принять структуру данных как входной сигнал и изменить ее и / или произвести другая структура данных в качестве вывода
иногда мы замечаем, что некоторые процедуры касаются только определенного вида структуры данных; удобно группировать эти процедуры вместе с их структурой данных и называть ее объект.
шаблон для создания объектов называется класс; объект считается экземпляр класса
мы можем заметить, что один класс очень похож на другой, так вместо копирования и вставки кода мы позволяем одному классу наследование из другой:подкласс наследует от суперкласса или "базовый класс". Таким образом, подкласс имеет доступ ко всем структурам данных и процедурам суперкласса и может определенным образом дополнять или переопределять их
Если мы вежливо просим объект сделать что-то для нас, а не грубо вызывать его процедуры напрямую, это называется сообщение проходя, даже если фактическое "сообщение" не передается. Радость здесь в том, что многие различные объекты могут понимать одно и то же сообщение, что приводит к понятию полиморфизм. Например, мы можем попросить много различных видов документов напечатать себя, и каждый из них отвечает соответствующим образом.
язык, который поддерживает объекты (через классы или нет) с передачей сообщений и наследованием, называется объектно-ориентированное. Если нет наследование, язык просто объектно-ориентированный.
удачи в учебе!
Procedural является частью процедурного / функционального / логического (или логически ориентированного) различия (сравните c, lisp и prolog) между различными способами описания того, что должна делать программа.
ориентация объекта ортогональна этой другой идее и описывает средство группировки подпрограмм с данными. C++ и java-процедурные языки с объектно-ориентированными функциями; fortran77-процедурные языки без объектно-ориентированных функций. Common lisp поддерживает ориентацию объектов; некоторые старшие шепелявят иначе. Простой ванильный пролог не поддерживает объекты, и я не могу назвать логически ориентированный язык, который делает (я не занимаюсь логически ориентированным программированием, он находится в моем списке вещей, которые нужно делать, когда я есть некоторые обильное свободное время. Я едва занимаюсь функциональным программированием).
однако, как отмечали другие, правильное объектно-ориентированное мышление меняет способ программирования так же, как и переход от процедурного к функциональному.
кстати ... я вижу "процедурные" использовали много, чтобы отличить не объектно-ориентированные процедурные языки от их объектно-ориентированных собратьев, но я думаю, что это плохое использование, вызванное отсутствием чистого прилагательного для "не объектно-ориентированного". YMMV.
его легче понять в контексте, посмотрите на другие абстракции, введенные между языками.
ключевым различием между языком ассемблера и процедурным языком, таким как C или Pascal, является введение абстракции "процедура". Люди, пишущие ассемблерный код, создают процедуры, но его жесткий и подверженный ошибкам процедурный язык дает вам инструменты для облегчения.
разница между процедурным языком и языком OO, таким как C++, является "объектная" абстракция. Люди, которые пишут "c", часто создают концептуальные объекты но его трудно и ошибки склонны, язык OO дает вам инструменты, чтобы сделать его проще.
такие вещи, как петь# от Microsoft (или Erlang) добавьте абстракцию сообщения/процесса в язык. Конечно, вы можете передавать сообщения и создавать процессы в сборке, C или C++, но Sing# облегчает это.
все сводится к одному машинному коду, эти абстракции исключительно для пользы нашего мозга, а не компьютера.
в процедурной программе вы разделяете большую проблему на небольшие проблемы и абстрагируете каждую из этих маленьких проблем как процедуру. Это называется процедурной абстракцией.
в объектно-ориентированных программах вы анализируете проблему как некоторые объекты, так и взаимодействие между объектами. Это называется абстракцией объекта.
разница составляет
Программирование, ориентированное на процедуру - придает важность алгоритму, а не данным.Этот способ программирования концентрируется на процедурах i.e методы для выполнения конкретной задачи и обмена их структурой данных. Он следует за нисходящими структурами.
пример : Pascal и C
объектно-ориентированное программирование - придает значение данным, а не алгоритму. Он следует за структурами снизу вверх.Каждая вещь рассматривается как объект. Каждый объект имеет своя структура и процедура данных. Он включает в себя такие функции, как скрытие данных,полиморфизм, инкапсуляция и передача сообщений. Пользователям не придется беспокоиться, что внутри этих объектов , при использовании их в своих программах.
пример : C++ и Java
Это упрощенный ответ.
в истинном языке OO единственное процедурное кодирование выполняется внутри объекта.
C не имеет объектов, а C++ - это язык, который поддерживает объекты. Java, с другой стороны, все является объектом(кроме примитивов). Все печатается.
- Линейная прогрессия происходит внутри объектов, но сами объекты являются просто коллекциями кода и данные.
Это зависит от того, как вы определяете ООП. С точки зрения Java-подобных ООП, где вы вызываете методы на объектах, процедурное программирование почти то же самое. Насколько я могу сказать, вы можете эмулировать все принципы ООП (инкапсуляция, абстракция, полиморфизм, наследование) на процедурном языке, таком как C. доказательство этого GObject, в некоторой степени Objective-C и многие другие реализации языка ООП с использованием C, такие как cPython. Это делается с помощью структур и работает на этих структурах использование функций:
typedef struct {
Object *isa;
String *name;
Date *birthday;
} Person;
Person *Person_new();
String *Person_name(Person *self);
void Person_setName(Person *self, String *newName);
// ...
интерфейс очень похож на ООП. Это действительно не позволяет полиморфизма, но это также возможно. Он очень похож на интерфейс Python, за исключением того, что атрибуты отдельно от "методов":
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
Я выбрал Python для примера, потому что" self " является явным, как в Примере C. Многие языки ООП, такие как Java, абстрагируют это.
есть также Smalltalk-подобный ООП, где сообщения отправляются объектам, а не чем вызов методов объектов. Разница тонкая на первый взгляд, но она обеспечивает много силы и гибкости. Это также может быть реализовано на процедурных языках, как доказано Objective-C.
объектно-ориентированное программирование не обязательно является типом языка, а скорее парадигмой. Объектно-ориентированные языки, такие как Java, Python, Ruby и т. д., обеспечивают синтаксический сахар для легкого управления объектами, и это основное различие между "процедурными языками" и "объектно-ориентированные языки".
действительно, библиотека или, скорее, набор функций, работающих на структуре, совпадает с объектом в C++. На самом деле c++ реализован именно таким образом.
много интересных моментов тут уже писали.
процедурное программирование обычно не использует такое соединение данных и поведения в "объект". Я видел, как это делается в C раньше, но это было не очень красиво и слишком много обезьяньего бизнеса, чтобы приблизиться к тому, что можно сделать, скажем, с C++.
одна из идей объектно-ориентированного развитие состоит в том, что я не должен быть в состоянии возиться с вашими данными любыми средствами, кроме тех, которые вы предоставили. Если вы предоставите мне только хорошо продуманный интерфейс, вы можете держать меня честным. Теперь, если вы используете процедурный подход, и вы посылаете мне структуру, которая не имеет встроенной защиты, ну, тогда я могу делать, что хочу, и если я тупой или злой, я могу изменить то, что вы не хотите, чтобы я менял.
конечно, вы можете обойти объект, если вы умны, но ты должен уйти с дороги, чтобы сделать это.
Это не полный, но это один аспект.
способ реализации C++ просто делает программирование OO похожим на процедурное программирование. Вам нужно немного изменить свое мышление.
в C++ объекты имеют методы, которые являются просто процедурами, которые действуют на объект. Но в реальном OO paradiam вы должны думать о методах как о потенциальных сообщениях, которые объект может получить (т. е. буквы). Объект получает сообщение (параметры представляют полезную нагрузку сообщения, т. е. содержимое письма) и изменяет его состояние основываясь на сообщении.
для довольно наглядного примера разницы между процедурным и OO попробуйте изучить Smalltalk. В Smalltalk все, и я имею в виду, что все является объектом. Нет операторов if или while-циклов. Вы достигаете этой функциональности, отправляя сообщения в (a.к. a. вызов методов on) другие объекты. Поначалу у тебя действительно кружится голова, но я думаю, ты быстро поймешь, что такое ОО.