Объектно-ориентированное программирование — это сравнительно молодая концепция, получившая широкое распространение только в середине 1980-х гг. До этого программирование было исключительно процедурным. Что отличает объектно-ориентированное программирование от процедурного? Отвечая на этот вопрос, можно выделить три основных принципа объектно-ориентированного программирования: абстракцию, инкапсуляцию, наследование.
Главным преимуществом объектно-ориентированного подхода является широкое использование инкапсуляции. Инкапсуляция (или скрытие реализации) позволяет создавать программу в виде отдельных, в большей или меньшей степени изолированных блоков. Почему программу приходится разбивать на такие блоки? Вы имеете уже достаточный опыт в написании сценариев, чтобы понимать, что, каким бы опытным ни был специалист, проследить логику кода из более чем 3-5 тысяч строчек ему не удастся — это просто выше человеческих интеллектуальных способностей. Современные же программы образованы миллионами и десятками миллионов строчек кода. Естественно, что написать конкурентноспособный коммерческий продукт один человек вряд ли может. Над созданием программ работают группы кодеров, и порой весьма значительные (так, штат Microsoft — многие тысячи программистов и тестеров). Каждый из программистов в таких командах создает свой фрагмент кода. Далее все фрагменты объединяются в единый блок, производятся тестирование, отладка и т. д.
Подумайте, если бы область видимости для всех фрагментов программы была единой — какие огромные проблемы возникли бы, например, из-за конфликта имен. Чтобы избежать этого, каждый программист должен был бы знать, как именно peaлизован участок кода, написанный его коллегой. А если переменных в программе тысячи? В этом случае основное время кодера ухолило бы на подбор идентификаторов, а не на создание алгоритма.
|
Решением описанной проблемы является инкапсуляция кода. Инкапсулированный фрагмент программы может быть представлен в виде «черного ящика», получающего на входе данные и выдающего на выходе результат. Переменные и функции инкапсулированного кода обладают локальной видимостью, поэтому случайно изменить их извне невозможно. Это решает проблему конфликта имен. При использовании инкапсуляции кода программист совершенно не должен задумываться о том, какреали-зованы остальные блоки программы. Он должен знать лишь то, что блок X выполняет те или иные задачи, и иногда — в какой форме он принимает данные на обработку. Поэтому инкапсуляция значительно облегчает разработку программ — создать без нее код более чем из тысячи строчек очень сложно. Инкапсуляция присуща не только объектно-ориентированному программированию. Так, в процедурном программировании она реализуется, например, при помощи подпрограмм (как вы помните, в ActionScript подпрограммы называются функциями). Однако в объектно-ориентированном программировании ее применение значительно расширяется благодаря введению понятия объекта.
Объект — это группа переменных и подпрограмм, объединенных в одну структуру по принципу выполняемых функций. В объектно-ориентированном программировании переменные объекта принято называть свойствами, а подпрограммы — методами. Свойства определяют состояние объекта, методы — его поведение. Методы, как правило, служат для изменения состояния объекта, т. е. при вызове нужным образом переопределяют его свойства, Свойства и методы объекта могут обладать разной степенью доступности. Они могут быть внутренними — при этом извне к ним нельзя получить доступ, допускающими только чтение, позволяющими чтение и переопределение, и наконец, доступными для чтения, удаления и переопределения. Разная степень доступности свойств позволяет минимизировать вероятность сбоя в работе всей системы при ошибочном удалении или переопределении одного из свойств. В ActionScript свойства и методы всех встроенных объектов защищены от удаления и перечисления циклом for—in, для большинства недопустимо также переопределение.
|
Смысл введения понятия «объект» достаточно очевиден. Во-первых, все методы и свойства, выполняющие задачи одного типа, можно собрать в одном месте, что значительно повышает общую стройность программы. Во-вторых, возможно инкапсулировать переменные и подпрограммы.
Польза от этого огромна. Например, слияние строк и объединение массивов выполняют методы с одним именем — concat(). Подобная перегруженность идентификатора возможна потому, что данные методы разделены по разным объектам. В-третьих, понятие объекта чрезвычайно близко к стереотипам нашего мышления, что делает программирование на объектно-ориентированном языке более интуитивным по сравнению с процедурным программированием. В этом проявляется одна из основных концепций объектно-ориентированного программирования — абстракция.
|
Часто в программе должно быть несколько однотипных объектов. Создавать их копированием кода не очень технично, так как это приведет к увеличению размера программы. Обычно объекты формируются на базе шаблона, называемого классом, с использованием оператора new. Например, строка new Ball() создаст новый объект класса Ball. Объекты класса называют его экземплярами.
Все методы и свойства, которые должны быть присущи объект, прописываются в его классе. Роль объекта и класса объектов не ограничивается объединением и инкапсуляцией переменных и подпрограмм. С ними связано второе важнейшее понятие объектно-ориентированного программирования — наследование.
Наследование — это передача переменных и функций между двумя независимыми модулями программы. Зачем нужно наследование? Прежде всего, оно позволяет минимизировать размер программы, а также трудоемкость ее создания. Представьте, что вы решили написать собственный графический редактор и вам надо разработать инструменты Line и Rectangle. Очевидно, что часть методов в объектах, их реализующих, будет одинакова. Например, идентичны в них будут методы, рисующие прямую линию. Имеет смысл данные методы вынести в отдельный объект, а в объектах Line и Rectangle оставить пометку о том, что если методы с такими именами потребуются, то они должны быть позаимствованы в хранящем их объекте. При этом отпадает необходимость дважды переписывать один и тот же код, а также сокращается длина программы.
Как вы помните, объекты создаются на базе определений классов. При этом часть свойств и методов может передаваться объекту непосредственно, а часть им наследуется. Непосредственно переносятся на объект те свойства и методы, которые должны иметь для каждого экземпляра класса индивидуальные значения. Те же компоненты определения класса, которые должны быть одинаковы для всех объектов, ими наследуются.
Класс может наследовать свойства другого класса. При этом данный класс будет являться по отношению к объектам первого суперклассом. Вообше протяженность цепочки наследования может быть любой. В некоторых языках цепочка наследования может даже ветвиться.
Важнейшей концепцией объектно-ориентированной модели является полиморфизм. Как следует из названия этого понятия, оно должно означать множественность форм. И действительно, полиморфизм обозначает способность объекта менять форму в процессе выполнения программы.
Если вы новичок в программировании, приведенное описание принципов объектно-ориентированного программирования может показаться вам малопонятным. В этом случае попробуйте связать в своем сознании понятия объектно-ориентированного программирования с предметами из реальной жизни. Это можно сделать, так как объектно-ориентированное программирование разрабатывалось именно для того, чтобы «очеловечить» программирование, сделать написание программ более близким особенностям нашего мышления.
Попробуем сопоставить понятия объектно-ориентированного программирования с обычным котом. Действительно, вполне можно считать, что идущий по крыше кот — это объект. Он обладает свойствами — окрасом, размером, возрастом и пр. Свойства кота делятся на индивидуальные (к примеру, цвет глаз) и присущие всему множеству (называемому в объектно-ориентированном программировании классом) котов (например, строение сердца). В свою очередь класс котов во многом схож с классом млекопитающих (например, количеством лап или способом вскармливания потомства) и, следовательно, является его подклассом. Любой класс может порождать подклассы, наследующие его свойства — так, в вид «кот домашний» входят тысячи самых разнообразных пород. В этом выражается концепция наследования. Коту присущи методы — алгоритмы, меняющие его свойства. К примеру, хлопок холодильника — безотказный метод, меняющий свойство положения кота на значение, совпадающее с координатой кухни. Чтобы позвать нашего питомца на обед, совсем не обязательно знать его анатомию и особенности нервной деятельности.
Для этого достаточно владеть внешним «интерфейсным» методом «кис-кис». В этом заключается еще один важный принцип объектно-ориентированного программирования — инкапсуляция (или скрытие реализации). На действие одного и того же метода разные коты могут реагировать поразному. Так, услышав лай собаки, более осторожное животное залезет на дерево, а более смелое продолжит спать как ни в чем не бывало. В терминах объектно-ориентированного программирования подобное поведение объектов одного класса называется полиморфизмом.