2009-02-10 3 views
28

Я довольно новичок в программировании, но я читал интересные обсуждения по StackOverflow о различных подходах к программированию. Я все еще не на 100% понимаю, какая разница между процедурным программированием и объектно-ориентированным программированием. Похоже, что объектно-ориентированное программирование по-прежнему использует процедуры (методы), но все организовано иначе, потому что объект является звездой шоу. Но мне кажется, что процедуры все же позволяют вам делать все то же самое. Как и в C, вы можете поместить все свои аналогичные процедуры в библиотеку. Неужели вы не могли сказать, что библиотека в C похожа на объект в C++?В чем разница между процедурной программой и объектно-ориентированной программой?

+0

Cf. [этот старый вопрос SO] (http://stackoverflow.com/questions/552336/oop-vs-functional-programming-vs-procedural) – jogojapan

+1

Может быть перемещен в Programmers SO возможно – Kromster

ответ

13

Разница между двумя является тонкой, но значительной.

В процедурной программе модули взаимодействуют посредством состояния чтения и записи, которое хранится в общих структурах данных.

В объектно-ориентированной программе модули в виде объектов взаимодействуют путем отправки сообщений другим объектам.

+0

У меня есть сомнения. Является ли Java процедурным языком? –

6

Разница заключается в том, что объекты имеют процедуры и связанные с ними данные в одном и том же месте - процедурные языки используют «структуры» (вещи, которые хранят связанные данные вместе), которые сохраняют данные отдельно от процедур. Фактически все, что вы делаете на языке OO, должно быть возможным на процедурном языке с комбинацией структур и процедур.

Основное различие заключается в помышления, что языки OO ставит программистов в.

1

Это упрощенный ответ.

  • В истинном языке OO только внутри процедурного кодирования выполняется внутри объекта.

  • C не имеет объектов, а C++ - язык, который поддерживает объекты. Java, с другой стороны, все является объектом (кроме примитивов). Все напечатано.

  • Линейная прогрессия происходит внутри объектов, но сами объекты представляют собой только коллекции кода и данных.
+0

'... самим объектам являются только коллекции кода и данных ». –

+0

@ Рихард, спасибо, что указал на мое упущение. Я исправлю это. – WolfmanDragon

21

Вы можете запрограммировать процедуры на большинстве языков OO, но мощность OO зависит от способности наследовать, инкапсулировать и абстрагироваться от процедурной логики. Я думаю, что вы правы, библиотека должна выглядеть как класс. Он должен обладать собственной областью и инкапсулировать логику функций с значимыми именами.

+3

В дополнение к вашему ответу, наследование, инкапсуляция и полиморфизм - это три столпа ООП. –

4

Процедура является частью процедурного/функционального/логического (или логически-ориентированного) различия (сравнение c, lisp и пролога) между различными способами описания того, что должна делать программа.

Ориентация объекта ортогональна этой другой идее и описывает средство группировки подпрограмм с данными. C++ и java - это процедурные языки с объектно-ориентированными функциями; fortran77 - это процедурные языки без объектно-ориентированных функций. Common lisp поддерживает объектную ориентацию; некоторые старые лисы не делают. Простой валидный пролог не поддерживает объекты, и я не могу назвать логически ориентированный язык, который делает (я не занимаюсь логико-ориентированным программированием, это в моем списке вещей, когда у меня есть какое-то обильное свободное время. едва ли функциональное программирование).

Как отмечают другие, в то же время правильное объектно-ориентированное мышление меняет порядок программирования, а также переход от процедурного к функциональному.


BTW-- Я вижу «процедурный» использовали много различать не объектно-ориентированные языки процедурные от их объектно-ориентированных братьев, но я думаю, что это плохое использование обусловлено отсутствием чистой прилагательного для «не объектно-ориентированного». YMMV.

+0

"логически ориентированный"? ; -P – Shog9

+0

Вместо «логического», чтобы избежать катастрофы типа «Я не могу назвать логический язык ...»? Да, я это вижу. – dmckee

+0

@ Shog9: Это лучше? – dmckee

31

В процедурной программе код является королем, а данные подчинены. Другими словами, у вас есть программы, которые действуют на данные, и они обычно не связаны жестко.

В мире ОО объекты являются основным предметом интереса. Объект состоит из данных и кода, которому разрешено воздействовать на эти данные, и они очень плотно связаны. Это концепция инкапсуляции, скрытия информации.

Например, предположим, что у вас есть номер, и вы хотите его удвоить. Процедурный способ сделать это:

n = n * 2 

Код здесь вполне явно умножает п на 2 и сохраняет результат обратно в п.

ОО способ сделать это, чтобы отправить «сообщение» на номер объекта, говоря его удвоить себя:

n.double(); 

Преимущество этого называется полиморфизмом. Что произойдет, когда вы решите, что хотите удвоить строку, например «bob». В процедурном мире вам нужно будет предоставить больше кода для удвоения, но вам также придется вызывать этот код по-разному.

С помощью OO вы создаете строковый объект, который также может принимать сообщение «double». Код для двойной строки относится к строковому объекту, поэтому он знает, что он должен действовать по-разному на числовой объект. Если он решил, что «боб» * 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() независимо от того, что фактический тип х был (число или строка) и он будет знать, какой код запускать - это значительно упрощает ваш код. Вы можете удвоить целое число, строки, матрицы, сложные числа, реалы, размеры окон на вашем мониторе и всевозможные вещи.

И вы правы, библиотеку C можно сделать похожими на объекты. Классическим примером является stdio.h - вам все равно что a FILE* на самом деле указывает на то, что он будет вести себя определенным образом. FILE*, fopen(), fclose() и другие функции представляют собой класс сортов, представляющий возможности ввода-вывода C.

+0

Отличное объяснение. Я удивлен, что это было выбрано как лучший ответ. Я думаю, это действительно прибило его. – 2009-02-10 17:49:01

+0

Вопрос: Я понимаю, как ваш пример представляет концепцию полиморфизма, но я не уверен, как он представляет инкапсуляцию. Это потому, что двойная функциональность теперь завернута в небольшую модульную функциональность, называемую методом? Как только у нас есть метод, у нас есть инкапсуляция? – 2009-02-10 18:44:36

+1

@WO, инкапсуляция - это скрытие данных или кода. Инкапсуляция кода - это то, что позволяет полиморфизм, поскольку теперь код принадлежит объекту, а не имеет внешний код, действующий на объект. Вы говорите объекту, что делать, а не как это делать. Он знает, как это сделать. Encaps/polymorph тесно связаны. – paxdiablo

8

OO в основном представляет собой набор разума. Вы можете запрограммировать OO на C (если вы действительно хотите ...), и вы можете отлично иметь процедурный код на C++/Java; я имею в виду, даже если вы используете классы на поверхности, он все равно может быть процедурным.

Идея OO - это абстракция состояния. Вместо «мышления» в терминах «группировки данных» вы «думаете» в терминах «объектов», где объект является «интерфейсом» для «группировки данных и способов управления этими данными».

Все это звучит философски, потому что это.

Здесь есть что сказать, и это не может быть сказано в небольшом сообщении СО, поэтому я оставлю его здесь.

UPDATE
Как уже упоминалось в Flanagan's answer, ОО языков реализации конструкции, которые используют эту абстракцию.

Я имею в виду, что вы могли бы технически «взломать» классы и полиморфизм с точки зрения структур, функций и указателей функций.

Вот пример OO in C

0

Много интересных моментов уже упомянутых здесь.

Один из способов думать об этом заключается в том, что в OO у вас есть идея «объектов», которые являются вещами, которые присущи им характеристикам и поведению. Обычно они имеют какой-то публичный «интерфейс», который предоставляет механизм для получения некоторой информации о них, но сам объект, или, скорее, его «класс», ограничивает доступность информации. Внутренности объекта не подвергаются публике, потому что обычно нет необходимости знать грязные детали «под капотом» объекта. Таким образом, объектно-ориентированные программы используют эту конструкцию, а также другие вещи.

Процедурное программирование обычно не использует такую ​​связь данных и поведения в «объект». Я видел, как это делалось на C раньше, но это было не очень и слишком много для бизнеса обезьян, чтобы приблизиться к тому, что можно было бы сделать, скажем, на C++.

Одна из идей, лежащих в основе объектно-ориентированного развития, заключается в том, что я не могу уклоняться от ваших данных любыми способами, кроме тех, которые вы предоставили. Если вы предоставите мне только хорошо продуманный интерфейс, вы можете держать меня честным. Теперь, если вы используете процедурный подход, и вы присылаете мне структуру, которая не имеет встроенных защит, тогда я могу делать все, что захочу, и если я тупой или злой, я могу изменить то, что вы, возможно, не хотите, чтобы я изменение.

Предоставлено, вы можете обойти объект, если вы умны, но вы должны уйти с дороги, чтобы сделать это.

Это не полный, но это один аспект.

0

Способ реализации C++ просто делает программирование OO очень похожим на процедурное программирование. Вам нужно слегка передумать.

В объектах C++ есть методы, которые являются просто процедурами, действующими на объект. Но в реальном параде OO вы должны думать о методах как о потенциальных сообщениях, которые может получить объект (т.е. письма). Объект получает сообщение (параметры представляют полезную нагрузку сообщения, то есть содержание письма) и изменяет его состояние на основе сообщения.

9

IMHO, объектно-ориентированное программирование - это концепция, которая существует на более высоком уровне абстракции, чем процедурное программирование. Эти два не являются взаимоисключающими в том, что отдельные методы в программе OO выглядят почти так же, как отдельные функции в процедурной программе. Это контрастирует, например, с функциональным программированием, которое требует совершенно иного мышления. Кроме того, вы можете писать процедурно на языке OO, делая все статичным и т. Д. Вы можете быть человеческим компилятором и эффективно писать OO-код на C, используя множество указателей на функции и кастинг с указателем структуры.

OO, то, скорее, является философией дизайна и мировоззрением, чем чем-то жестким определением. Это требует, чтобы наследование, полиморфизм и т. Д. Использовались в качестве основных шаблонов при структурировании вашего кода, и этот синтаксис должен был быть предоставлен, чтобы сделать это выразительным, не прибегая к низкоуровневым трюкам. Это требует, чтобы вы считали код, который действует на состояние коллекции данных как свойство данных, а не сама процедура, которая существует сама по себе. Он не черный и белый. Ваш код может быть «больше» или «меньше» OO в зависимости от того, насколько сильно вы полагаетесь на наследование, полиморфизм, классы и «методы как свойство данных» мировоззрение как средство структурирования и объяснения/понимания вашего кода.

+0

Хороший вопрос о различии между кодом OO и процедурным кодом и языками OO и процедурные языки. Увеличен. –

6

[простите за стиль праймера, это поздно, и я устал]

процедур данных процесса - данные, применить некоторую обработку, получить данные из

иногда, некоторые элементы данных связаны с некоторые из других элементов данных, и их удобно группировать в структуру данных , которая затем может обрабатываться и обрабатываться как единое целое.

теперь наша процедура может занять структуры данных в качестве входных данных и изменить его и/или производить другую структуру данных в качестве вывода

иногда мы замечаем, что некоторые процедуры касаются только определенного рода структуры данных; удобно группировать эти процедуры вместе со своей структурой данных и называть его объектом .

шаблон для создания объектов называется класс; объект назовет экземпляра класса

мы можем заметить, что один класс очень похож на другом, так что вместо копирования и код вставки мы позволяем один класс наследуют от другого: подкласса наследует от суперкласс или «базовый класс». Таким образом, подкласс имеет доступ ко всем структурам данных и процедурам суперкласса и может каким-то образом дополнять или переопределять их

, если мы вежливо попросим объект что-то сделать для нас, а не жестоко называть его процедуры непосредственно , это называется сообщение об ошибке, даже если фактическое 'сообщение' не передается. Радость здесь заключается в том, что многие различные типы объектов могут понимать одно и то же сообщение, что приводит к понятию полиморфизма . Например, мы можем запросить много разных документов для печати, и каждый из них отвечает соответствующим образом.

язык, который поддерживает объекты (через классы или нет) с передачей сообщений и наследованием, называется объектно-ориентированным. Если наследования нет, то это всего лишь объект-основанный.

Удачи вам в учебе!

+4

Это превосходно! Не представляю, как это было бы, если бы ты не устал. Я сохраняю это. – 2009-02-10 16:45:41

+0

@ [Willem Obst]: Спасибо - если бы у меня было больше времени, это было бы короче ;-) –

+4

Вау!Я бы хотел, чтобы мои учителя могли объяснить все так же ясно, как и здесь. Спасибо за ваш вклад! –

2

Его легче понять в контексте, посмотрите на другие абстракции, введенные между языками.

Ключевое различие между языком ассемблера и процедурным языком, таким как C или Pascal, является введение абстракции «процедуры». Люди, записывающие код сборки, создают процедуры, но его жесткий и подверженный ошибкам, процедурный язык дает вам инструменты, облегчающие его.

Разница между процедурным языком и языком OO, например C++, является абстракцией объекта. Люди, которые пишут «c», часто создают концептуальные объекты but its difficult and error prone, язык OO дает вам инструменты, облегчающие его.

Такие вещи, как Sing# от Microsoft (или Erlang), добавляют абзац сообщения/процесса в язык. Конечно, вы можете выполнять передачу сообщений и создавать процессы в сборке, C или C++, но Sing # упрощает работу.

Все сводится к одному и тому же машинным кодам, эти абстракции предназначены исключительно для удобства наших мозгов, а не для компьютера.

15

Вы правильно заметили, что объектно-ориентированные программы во многом основаны на процедурной парадигме. Вы также правы в том, что синтаксически все, что действительно происходит, это то, что вы вызываете функции. Фактически, вы можете реализовать множество функций объектно-ориентированных языков, используя процедурные механизмы (например, указатели на функции в C++). Таким образом, вы можете сделать объектно-ориентированный дизайн и по-прежнему реализовывать его на процедурном языке (например, как это делали старые компиляторы C++).

Важность объектно-ориентированной парадигмы не так много в языковом механизме, как в процессе мышления и проектирования. В процедурном программировании мышление связано с операциями и разрушением этих операций с использованием других операций, группировкой их в модули и т. Д. Это означает, что данные или состояние попадают в второстепенное значение. Это похоже на математические операции.

С другой стороны, объектно-ориентированная парадигма говорит о том, что вам нужно думать о состоянии и операциях вместе как об объекте, а затем проектировать свою программу как взаимодействие между объектами, которые обмениваются состояниями и активируют операции.

1

Это зависит от того, как вы определяете ООП. С точки зрения 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 для примера, потому что «я» явно, как в примере C. Это много языков ООП, таких как Java.

Есть также Small-Stalk-подобный OOP, где сообщения отправляются объектам, а не вызовы методов на объектах. Разница на первый взгляд тонкая, но она обеспечивает большую мощность и гибкость. Это также может быть реализовано на процедурных языках, что подтверждается Objective-C.

Объектно-ориентированное программирование не обязательно является типом языка, а скорее парадигмой. Объектно-ориентированные языки, такие как Java, Python, Ruby и т. Д., Обеспечивают синтаксический сахар, чтобы легко манипулировать объектами, и это основное различие между «процедурными языками» и «объектно-ориентированными языками».

Действительно, библиотека, или, скорее, набор функций, работающих на структуре, такая же, как объект в C++. На самом деле C++ реализуется именно так.

0

Для справедливого примера разницы между процедурным и ОО попробуйте изучить Smalltalk. В Smalltalk все, и я имею в виду, что все является объектом. Нет if-операторов или while-loops. Вы достигаете этой функциональности, отправляя сообщения (на вызовы методов a.k.a.) на другие объекты. Сначала это заставляет вашу голову вращаться, но я думаю, вы быстро поймете, что такое OO.

2

В процедурной программе вы делите большую проблему на небольшие проблемы и отрисуете каждую из этих небольших проблем как процедуру. Это называется процедурной абстракцией.

В объектно-ориентированных программах вы анализируете проблему как некоторые объекты и взаимодействие между объектами. Это называется абстракцией объекта.

2

Разница заключается в

Процедуры ориентированного программирование - дает значение алгоритма, а не data.This способа программирования концентрируется на процедуры, то есть методы для выполнения конкретной задачи и разделить их структуру данных. Это следует за структурами сверху вниз.

пример: Паскаль и С

Объектно-ориентированное программирование - Дает значение данных, а не алгоритм. Это следует за нижними структурами. Вся вещь рассматривается как объект. Каждый объект имеет свою собственную структуру данных и процедуру. Он включает в себя такие функции, как скрытие данных, полиморфизм, инкапсуляция и передача сообщений. Пользователям действительно не нужно беспокоиться о том, что внутри этих объектов, используя их в своих программах.

пример: C++ и Java

Смежные вопросы