Объектно-ориентированное программирование: различия между версиями
Содержимое удалено Содержимое добавлено
SergeyJ (обсуждение | вклад) Нет описания правки |
Alan ffm (обсуждение | вклад) интервики |
||
Строка 3:
== Общие замечания ==
Объектно-ориентированная парадигма программирования не нова. Её истоки восходят к Симуле-67, хотя первая полная реализация была в Smalltalk-80. ООП (Объектно-ориентированное программирование) стало популярным во второй половине 80-х в таких языках, как С++, Objective C (другое расширение C), Object Pascal и Turbo Pascal, CLOS (ОО-расширение Lisp'a), Eiffel, Ada (в её последних воплощениях) и недавно
Ключевые черты ООП хорошо известны:
# Первая
# Вторая ключевая черта,
# Третья черта, известная как '''полиморфизм''', позволяет единообразно ссылаться на объекты различных классов (обычно внутри некоторой иерархии). Это делает классы ещё более удобными и делает программы, основанные на них, легче для расширения и поддержки.
Инкапсуляция, наследование и полиморфизм
''Алан Кей'' в свое время вывел пять основных черт языка Smalltalk
# '''Все является объектом.''' Объект как хранит информацию, так и способен ее преобразовывать. В принципе любой элемент решаемой задачи (дом, собака, услуга, химическая реакция, город, космический корабль и
# '''Программа
# '''Каждый объект имеет свою собственную «память» состоящую из других объектов.''' Таким образом программист может скрыть сложность программы за довольно простыми объектами. К примеру дом (достаточно сложный объект) состоит из дверей, комнат, окон, проводки и отопления. Дверь в свою очередь может состоять из собственно двери, ручки, замка и петель. Проводка так-же состоит из проводов, розеток и к примеру щитка.
# '''У каждого объекта есть тип.''' Иногда тип называют еще и классом. Класс (тип) определяет какие сообщения объекты могут посылать друг другу.
# '''Все объекты одного типа могут получать одинаковые сообщения.''' К примеру у нас есть 2 объекта: синяя и красная кружки. Обе разные по форме и материалу. Но из обеих мы можем пить (или не пить, если они пустые). В данном случае кружка
Самое лаконичное описание объекта предложил ''Буч'': «Объект обладает ''состоянием'', ''поведением'' и ''индивидуальностью''».
Строка 279:
=== Деструкторы и финализация ===
Свойство: Деструктор играет роль противоположную конструктору и обычно вызывается при уничтожении объекта. Если конструктор нужен большинству классов, то только некоторые из них нуждаются в деструкторе. Деструктор в основном используется для освобождения ресурсов, зарезервированных конструктором (или другими методами во время жизни объекта). Эти ресурсы включают память, файлы, базы данных, ресурсы Windows и
'''C++:''' деструкторы вызываются автоматически, когда объект выходит из области определения или когда вы удаляете объект, заведенный динамически. У каждого класса есть только один деструктор, который объявляется как ~Class(), где Class - имя класса. Если объект создан в куче, то он не может быть автоматически удален и если не объявить деструктор явно в программе, то происходит утечка памяти (в Java данная проблема решена сборщиком мусора).
'''OP:''' деструкторы похожи на деструкторы C++. <small>(Для деструкторов используется ключевое слово destructor [мое примечание
'''Java:''' В Java нет деструкторов. Объекты, на которые нет ссылок, уничтожаются сборщиком мусора, который работает в виде фоновой задачи и делает это автоматически (как описывалось ранее). Прежде чем уничтожать объект, сборщик мусора должен вызвать метод ''finalize()''. Однако нет никакой гарантии, что этот метод вызывается в каждой JVM. По этой причине, если вам нужно освободить ресурсы, вы должны добавить какой-нибудь метод, и убедиться, что он вызывается (эти дополнительные усилия не нужны в других ОО языках).
Строка 293:
Свойство: Общим элементом всех трех языков является присутствие трех спецификаторов доступа, указывающих на различные уровни инкапсуляции класса: public, protected, и private. Public означает: видимый любым другим классом, protected означает: видимый производными классами, private означает: отсутствие видимости извне. В деталях, однако, есть различия.
'''C++:''' В C++ вы можете использовать ключевое слово friend для обхода инкапсуляции. Видимость по умолчанию для класса
'''OP:''' В Object Pascal private и protected относятся только к классам других юнитов. В терминах C++, класс является дружественным для любого другого класса, определенного в том же юните (или файле исходного кода). В Delphi есть еще один модификатор доступа
'''Java:''' В Java отличие синтаксиса в том, что модификатор доступа повторяется для каждого элемента класса. А конкретнее, по умолчанию в Java используется friendly, это значит, что элемент видим для других классов этого же пакета (или файла исходного кода, как в OP). Подобным образом, protected означает видимость для подклассов, тогда как комбинация private protected соответствует protected в C++.
Строка 305:
Свойство: Важное различие между тремя языками заключается в организации исходного кода в файлах. Все три языка используют файлы в качестве стандартного механизма для запоминания исходного кода классов (в отличие от других ОО языков, таких как Smalltalk), но компилятор C++, в отличие от OP или Java, не понимает файлов. Эти же два языка работают с идеей модулей, хотя называют их по-разному.
C++: В C++ программист обычно помещает определение класса в файл объявлений, а определение методов
OP: В Object Pascal каждый файл исходного кода называется unit, и он делится на две
Строка 334:
== Классы и наследование ==
Свойство: Наследование у классов
C++: C++ использует слова public, protected, и private для определения типа наследования и чтобы спрятать наследуемые методы или данные, делая их приватными или защищёнными. Хотя публичное наследование наиболее часто используется, по умолчанию берётся приватное. Как мы увидим далее, C++
<source lang=cpp>
class Dog: public Animal {
Строка 372:
Свойство: В некоторых ОО языках каждый класс происходит по крайней мере от некоторого базового класса по умолчанию. Этот класс, часто называемый Object, или подобно этому, обладает некоторыми основными способностями, доступными всем классам. Фактически, все другие классы в обязательном порядке его наследуют. Этот подход является общим ещё и потому, что так первоначально делалось в Smalltalk.
C++: Хотя язык C++ и не поддерживает такое свойство, многие структуры приложений базируются на нём, вводя идею общего базового класса. Пример тому
OP: Каждый класс автоматически наследует класс TObject. Так как язык не поддерживает множественное наследование, все классы формируют гигантское иерархическое дерево. Класс TObject поддерживает RTTI и обладает некоторыми другими возможностями. Общей практикой является использование этого класса, когда вам нужно передать объект неизвестного типа.
Строка 410:
OP: В Object Pascal позднее связывание вводится с помощью ключевых слов virtual и dynamic (разница между ними только в оптимизации). В производных классах переопределённые методы должны быть отмечены словом override (это заставляет компилятор проверять описание метода). Рациональное объяснение этой особенности OP состоит в том, что разрешается больше изменений в базовом классе и предоставляет некоторый дополнительный контроль во время компиляции.
Java: В Java все методы используют позднее связывание, если вы не отметите их явно как final. Финальные методы не могут быть переопределены и вызываются быстрее. В Java написание методов с нужной сигнатурой жизненно важно для обеспечения полиморфизма. Тот факт, что в Java по умолчанию используется позднее связывание, тогда как в C++ стандартом является раннее связывание,
Примечание: Позднее связывание для конструкторов и деструкторов. Object Pascal, в отличие от других двух языков, позволяет определять виртуальные конструкторы. Все три языка поддерживают виртуальные деструкторы.
Строка 422:
OP: Object Pascal для выделения этих методов использует ключевое слово abstract. Кроме того, абстрактными классами являются классы, имеющие или наследующие абстрактные методы. Вы можете создать объект абстрактного класса (хотя компилятор выдаст предупреждающее сообщение). Это подвергает программу риску вызвать абстрактный метод, что приведёт к генерации ошибки времени выполнения и завершению программы.
Java: В Java и абстрактные методы, и абстрактные классы отмечаются ключевым словом abstract (действительно, в Java обязательно определять как абстрактный, класс, имеющий абстрактные методы,
== Множественное наследование и интерфейсы ==
Строка 428:
Свойство: Некоторые ОО языки допускают наследование более чем одному базовому классу. Другие языки позволяют вам наследовать только от одного класса, но дополнительно позволять вам наследовать также от многочисленных интерфейсов или чисто абстрактных классов, то есть классов, состоящих только из виртуальных функций.
C++: C++
Java: Java, как и Object Pascal, не поддерживает множественное наследование, но полностью поддерживает интерфейсы. Методы интерфейсов допускают полиморфизм, и Вы можете использовать объект, осуществляющий интерфейс, когда ожидается интерфейсный объект. Класс может наследовать или расширить один базовый класс, но может осуществить (это
public interface CanFly {
public void Fly();
Строка 450:
'''C++:''' первоначально не поддерживал RTTI. Это было добавлено позже для динамического преобразования типа (dynamic_cast) и сделало доступной некоторую информацию о типе для классов. Вы можете запросить идентификацию типа для объекта, и проверить, принадлежат ли два объекта одному классу.
'''OP:''' поддерживает и требует много RTTI. Доступен не только контроль соответствия и динамическое преобразование типов (с помощью операторов ''is'' и ''as''). Классы генерируют расширенную RTTI для своих ''published'' свойств, методов и полей. Фактически это ключевое слово управляет частью генерации RTTI. Вся идея свойств, механизм потоков (файлы форм
'''Java:''' как и в Object Pascal, в Java тоже есть единый базовый класс, помогающий следить за информацией о классе. Безопасное преобразование типов (type-safe downcast) встроено в этот язык. Метод ''getClass()'' возвращает своего рода метакласс (объект класса, описывающего классы), и Вы можете применить функцию ''getName()'' для того, чтобы получить строку с именем класса. Вы можете также использовать оператор ''instanceof''. Java включает в себя расширенную RTTI для классов или интроспекцию, которая была введена для поддержки компонентной модели JavaBeans. В Java существует возможность создавать классы во время исполнения программы.
Строка 467:
=== Обработка исключений ===
Свойство: Основная идея обработки исключений
C++: C++ использует ключевое слово throw для генерации исключения, try для отметки охраняемого блока и catch для записи кода обработки исключения. Исключения
OP: Object Pascal использует подобные ключевые слова: raise, try, и except и обладает подобными свойствами. Единственное существенное отличие состоит в том, что опустошение стека не производится, просто потому, что в стеке нет объектов. Кроме того, вы можете добавить в конце блока try слово finally, отмечая блок, который должен выполняться всегда, независимо от того, было или нет вызвано исключение. В Delphi классы исключений
Java: Использует ключевые слова C++, но ведёт себя как Object Pascal, включая дополнительное ключевое слово finally. (Это общее свойство всех языков со ссылочно-объектной моделью, оно включено Borland также и в C++Builder 3.) Присутствие алгоритма сборки мусора ограничивает использование finally в классе, который распределяет другие ресурсы, кроме памяти. Также Java строже требует, чтобы все функции, которые могут вызвать исключение, описывали в соответствующем блоке, какие исключения могут быть вызваны функцией. Эти описания исключений проверяются компилятором, что является хорошим свойством, даже если оно подразумевает некоторую дополнительную работу для программиста. В классах Java объекты-исключения должны наследовать классу Throwable.
Строка 477:
=== Шаблоны (обобщенное программирование) ===
Свойство: Обобщенное программирование
'''C++:''' есть шаблонные классы и функции, отмечаемые ключевым словом ''template''. Стандартный C++ включает обширную библиотеку шаблонов, называемую STL (Standart Template Library ,Стандартная библиотека шаблонов), которая поддерживает специфический и мощный стиль программирования: обобщенное программирование. C++
'''OP:''' нет шаблонов. Контейнерные классы обычно строятся как контейнеры объектов класса ''TObject'', а затем уточняются для необходимых объектов.
Строка 491:
C++: Я уже упомянул множественное наследование, виртуальные базовые классы и шаблоны. Эти свойства отсутствуют в двух других ОО языках. В C++ есть ещё перегрузка операторов, тогда как перегрузка методов присутствует также в Java и была недавно добавлена в Object Pascal. C++ позволяет программистам перегружать и глобальные функции. Вы можете перегрузить операторы преобразования типов, написав конвертирующие методы, которые будут вызываться «за кулисами». Объектная модель C++ требует копировать конструкторы и перегружать операторы присваивания, в чем не нуждаются остальные два языка, поскольку базируются на ссылочно-объектной модели.
Java: Только Java поддерживает многопоточность непосредственно в языке. Объекты и методы поддерживают механизм синхронизации (с ключевым словом synchronized): два синхронизированных метода одного класса не могут выполняться одновременно. Для создания нового потока вы просто наследуете от класса Thread, перегружая метод run(). Как альтернативу вы можете осуществить интерфейс Runnable (что вы обычно делаете в апплетах, поддерживающих многопоточность). Мы уже обсуждали сборщик мусора. Ещё одно ключевое свойство Java, конечно, идея переносимого байтового кода, но это не относится непосредственно к языку. Другое примечательное свойство
OP: Вот некоторые специфические черты Object Pascal: ссылки на классы, легкие для использования указатели на методы (основа модели обработки событий) и, в частности, свойства (property). Свойство
== Стандарты ==
Строка 501:
C++: Стандарт ANSI/ISO C++ явился завершением многотрудных усилий соответствующего комитета. Большинство авторов компиляторов, кажется, пытаются подчиняться стандарту, хотя есть ещё много странностей. Теоретически развитие языка должно на этом закончиться. На практике, инициативы вроде компилятора Borland C++Builder, конечно, не способствуют улучшению ситуации, но многие чувствуют, что C++ очень нуждается в визуальном окружении программирования. В то же время, популярный Visual C++ тянет C++ в другом направлении, например, с явным злоупотреблением макросов. (По моему личному мнению, у каждого языка есть собственная модель развития, и поэтому нет большого смысла в попытках использовать язык для того, для чего он не был предназначен.) Много новых возможностей будут введены новым стандартом C++ 0x.
OP: Object Pascal
Java: Компания-создатель Sun обладает торговой маркой Java. Однако Sun лицензирует его для продавцов других компиляторов, и убедило ISO создать стандарт Java, не создавая специальный комитет, а просто приняв предложения Sun как есть. Кроме формального стандарта, однако, Java требует высокосовместимых JVM. С недавней поры Sun выдвинула инициативу открыть исходные коды Java (OpenJDK) и сделать ее доступной для всех разработчиков в рамках лицензии GPL 2.
Строка 509:
Как я упоминал в начале, хотя я пытался исследовать эти языки, только сравнивая синтаксические и семантические характеристики, важно рассмотреть их в соответствующем контексте. Языки нацелены на различные потребности, что означает, что они решают разные проблемы разными способами и используются в очень разных средах программирования. Хотя как языки, так и их среда копируют характеристики друг друга, они были сконструированы для разных потребностей, и в этом вы можете убедиться, сравнивая их характеристики.
Цель C++
Можно определить, что успех этих трех языков зависит не от технических характеристик, которые я включил в эту статью. Финансовый статус Borland, операционная система управления Microsoft, популярность Sun в мире Internet, тот факт, что Java рассматривается как anti-Microsoft-овский язык, будущее броузеров Паутины и Win32 API, роль и признание модели ActiveX (из-за связанной с ней проблемой безопасности) и три уровня архитектуры Delphi
Просто имейте в виду, что «модный» становится все более частым словом в компьютерном мире. Как пользователи хотят иметь инструменты этого года (вероятно, по этой причине операционные системы называются по тому году, в котором они выпущены), программисты любят работать с последним языком программирования и первыми овладеть им. Можно наверняка утверждать, что Java
== Ссылки ==
Строка 522:
[[Категория:Объектно-ориентированное программирование|*]]
[[en:Object Oriented Programming]]
[[fr:Programmation/Programmation orientée objet]]
[[ja:オブジェクト指向]]
[[pl:Obiektowość w tworzeniu oprogramowania]]
[[pt:Programação Orientada a Objetos]]
|