![]() |
Модераторы: volvo877, Snowy, MetalFan |
![]() ![]() ![]() |
|
SPrograMMer |
|
||||
![]() Спамер :) ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 5.11.2004 Где: Краснодар Репутация: нет Всего: 6 |
Объектно-ориентированное программирование для начинающих на Паскале.
"Объектно-ориентированное..." - это значит работа с объектами. Что в нашей жизни мы можем назвать объектами? А все что угодно. Стол, за которым сидим, машина в которой едим, воздух, которым дышим, ... - Это все РЕАЛЬНЫЕ объекты и мы их можем хорошо представить, вообразить как они будут себя вести, что будут делать. Кстати, чем отличается, СТОЛ и САМОЛЕТ как объекты? Ну первая, пришедшая в голову мысль, что сравнивать их как-то не очень хочется, совсем они разные... Вот тут-то мы и пришли к одному из характеристик объектов, а именно к свойствам. Как Вы пытались сравнивать стол и самолет? Наверное пытались найти в них, что-то общее или наоброт то чем они отличаются. Ну так вот на самом то деле два приведенных выше объекта имеют много общего ![]() Вот первое, что мы должны понять это то что объекты характеризуются СВОЙСТВАМИ. А вот значения этих свойств у объектов может быть разное (материал изготовления, например). Давайте подумаем, чем есчо могут отличаться Самолет и Стол? Наверное манерой поведения, то есть их действиями и реакцией на определенные действия. Например Самолет будет иметь характеристику "Скорость", которая будет изменяться, а для Стола эта характеристика безсмысленна. Хорошо есть у нас свойство "скорость", а как ею распоряжаться? Самолет может покоиться на аэродроме, набирать скорость при взлете и тормозить при посадке. Что это такое: покой, набор скорости, торможение? К свойствам они наверное отновшения не имеют. Как например вы можете оценить свойство "набор скорости"? Можно конечно сравнивать с другими подобными объектами и говорить о понятиях быстрее, медленнее. Но к ООП это ни какого отношения иметь не будет. На самом деле с точки зрения ООП покой, набор скорости, торможение - это действия производимые объектом. Действия, в ООП их называют Методами, управляют Свойствами. Например Методы набор_скорости и торможение изменяют Свойство скорость, уменьшаю её или увеличивают. Кстати в классике ООП только методы могут изменять значения свойств, ну что бы не было безконтрольного их изменения из вне. Что например произойдет если скорость станет равной -34 км/ч? Да, методы призваны контролировать свойства, давая им осмысленные значения, и естествено правильный метод "торможение" никогда не допустит уменьшение скорости, когда оно достигнет нулевой отметки. ![]() Итак для объекта характерны свойства и методы. В программировании то же можно найти вагон и маленькую тележку "виртуальных" объектов. Может быть вы уже слышали про среду Delphi, в которой создаются приложения под Windows, там все рассматривается как объекты, например Кнопки, надписи, флажки, окна и само приложение - это все объекты. Для тренировки: какие свойтва есть у кнопки? Ну наверное, надпись на ней, цвет этой надписи, возможность изображения на кнопки картинки,.. и т д и т п. В среде DOS при программировании на обычном Паскале, то же можно найти кучу объектов. Например, среда Turbo Pascal (Borland Pascal), в которой есть меню, окна, диалоги, а это ведь то же объекты. Даже если у вас нет такого сложного графического интерфейса вы то же можете использовать ООП для решения своей задачи, например, задача решения квадратного уравнения. Ну ка скажите мне где здесь объекты?......А само уравнение - это и есть объект, Какие у него свойства? а наверное коэффициенты перед Х. А методы? наверное очень хороший метод я придумал: "РЕШЕНИЕ", в котором происходит непосредсвенное вычисление, наверное можно было сказать, что есть есчо и метод "Вычисление_дискриминанта", - это будет промежуточный метод ![]() Мир Объектно-Ориентированного программирования велик! Начнем его познавать с точки зрения языка Паскаль (хочу заметить что нижеследующие синтаксис, и теоретические выкладки сделаны опираясь на собственном опыте и предназначено для использования в DOS компиляторах Паскаля, например Turbo Pascal или Borland Pascal. Теория собсно может быть полезна и Delphi программисту, хотя есть кое-какие моменты в этом отношении, о чем разговор есчо будет) Любой объект в паскале это просто новый тип данных, объявляеммый в разделе описания типов Type с использованием специальной терминологии языка. Синтаксис будет следующим:
имена типов - о вашему усмотрению, но рекомендуется все типы начинать с буквы T. Для описания объктов используется ключевое слово object, заканчивается описание ключевым словом End. Очень напоминает объявление записи (record). Вместо точек пишутся члены класса..... тьфу, ну вот... сказал класса... Дело в том что есть некоторая "путаница" в терминологии в принципе понятие "объект" и "класс" - оба из ООП и очень близки по значению."Класс" - это описание, так сказать теоретическая часть ООП; "объект" - это КОНКРЕТНЫЙ ЭКЗЕМПЛЯР класса в оперативной памяти. Например, выше мы говори о самолетах. Термин "Самолет" - это класс, ни чего нам не говорящий о действительном объекте. А вот если мы с Вами сядем в первый класс какого-нить там Боинга-747, то будем иметь дело уже с конкретным экземпляром класса - т е с "объектом". В паскале слова класс как такового нет, хотя на самом деле подразумевается. То что мы с вами объявляем в разделе Type - в классике это класс, хотя и используем ключевое слово object, Ну а так как это тип данных => можно объявить переменную:
Это уже будет конкретный экземпляр класса, т е объект. В дальнейшем, то что касается описательной части я буду называть это КЛАССОМ (ибо привык уже ![]() Это сообщение отредактировал(а) SPrograMMer - 2.5.2005, 19:35 -------------------- животное = зверь законченный гентушник |
||||
|
|||||
SPrograMMer |
|
||||||||||||||||||||
![]() Спамер :) ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 5.11.2004 Где: Краснодар Репутация: нет Всего: 6 |
Итак мы знаем, что у объектов есть свойства, например, цвет, скорость, текущее состояние - все это данные, которым можно давать какие-то значения, тип данных у свойств различный, одни могут быть числами, другие- строки, третьи могут сами представлять из себя объекты...Ну так вот свойства - это данные, объявляются примерно так как запись:
Cо свойствами (данными) работают методы - подпрограммки (вспомните методы "торможение", "набор_скорости"). Описываются в классе с применением спецификаторов procedure и function.В самом объявлении, т е в классе, т е в разделе Type, описываются только заголовки подпрограмм. Итак наша машина обретает методы:
Реализация методов класса должна происходить отдельно, то есть нельзя сразув разделе Type писать операторы программы которые будут реализовывать нужный метод. Это надо делать после объявления. При этом снова указывается вид метода (подпрограмма или функция), затем делается ссылка на тип класса (к какому классу относится реализуемый метод) и наконец, через точку, имя реализуемого метода. По вкусу моно есчои параметры метода перечислить. Например, реализация методов "машины":
Конечно реализации всех этих методов "выпендреж", в первом можно было сразу написать Speed:=Speed+A*Time, во втором Speed:=0 - но надо же мне было что-там там придумать, да и к тому же машина не сразу ведь тормозит, так что метод EndMove немного приближен к реальности ![]() Теперь немного об обращениик членам объекта,а они - свойства и методы. Да, прежде чем обращатьсяк какому-нить члену объекта, этот самый объект надо заиметь в памяти:
Я уже упоминал как происходит реализация методов, точнее как озаглавливаются методы классов - через точку. То же происходит и при обращении к свойствами методам в объекте (т е в экземпляре класса):
Как видите все просто: имя переменной, ответственной за объект, точка (большая и жирная!),и свойсво или метод. Как и к записям, к объектам можно применять оператор With, например:
Если все оставить как есть то хорошего получится не очень-то много. Например, мы с вами "красили" машину, простым присваиванием значения свойству, ответственному за цвет машины. Аналогично мы можем изменить и другие свойсва, просто обратившись к ним, например:
ну что это, что это, за народное творчество понимаешь... Текущая скорость машины -34 км/ч Как скорость машины может быть отрицательна???! Ладно мы с вами не дуракии вот так с нашей бедной машиной явно поступать не собираемся, но вот сдадим мы её в прокат, не знакомому человеку....А он то, зараза такой, возьмет да и скажет: "Хочу скорость 100000000 км/ч", т е Car.Speed:=10000000;- такого тоже быть не может, что от машины тогда останется... Для того что бы такого не происходило свойства обычно "прячут" от глаз,и пользоваться разрешается только методами. В этом случае, если мы хотим изменять скорость как нам хочется добавим новый метод:
И теперь вместо Car.Speed:=-34и Car.Speed:=10000000; надо будет использовать метод ChangeSpeed:
Теперь видите как происходит контроль за значением свойств объекта? Да я есчо не расказал как же все запретить напрямую изменять свойства. Для этого их нужно по особому описать, сказать что они не доступны для "массового использования" т е личные они. Делается это с помощью ключевого слова private. А то что изменять можно (например, нам "по барабану" какого цвета машина) то сказать, что оно "публичное" - доступное широкому обозрению - ключевое слово public, закрытыми (не доступными) можно делать не только свойства класса но и его методы.Вот например как лучше объявить наш класс при описании:
Это сообщение отредактировал(а) SPrograMMer - 6.5.2005, 08:28 -------------------- животное = зверь законченный гентушник |
||||||||||||||||||||
|
|||||||||||||||||||||
SPrograMMer |
|
||||||
![]() Спамер :) ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 5.11.2004 Где: Краснодар Репутация: нет Всего: 6 |
Дальнейшее изучение ООП мы продолжим, решая практическую задачу. Нам надо рассмотреть такие "страшные" термины как "наследование", "полиморфизм" и "инкапсуляция". Кстати частично инкапсуляцию мы уже посмотрели и применили - это использование слов public и private для определения видимости членов класса вне его. Мы как бы заключили наш объектв "капсулу". Но капсулы бывают разные: одни полностью прозрачные, другие непрозрачные вовсе. Вот те которые прозрачны - их консистенция (то из чего они состоят) видна (в ООП соответсвует public).А непрозрачные капсулы предстовляют собой "черный ящик" - их содержимое нам неизвестно(private).
А практическая задача будет следующая: нам надо написать на паскале (пусть компилятором будет Borland Pascal), некую аналогию программы Paint, в которой можно рисовать графические примитивы, такие как точки, окружности, линии, прямоугольники, в том числе и закрашенные. На этой задаче я попробую объяснить что такое наследование и полиморфизм. Начнем. Но прежде немного теории про наследование. Наследование - это один из принципов ООП, позволяющий применять уже существующие классы, расширяя их функциональность. Опять отвлекусь на автомобили. Сколько их у нас может быть? Легковые автомобили (Ока, Москвич, Волга и т д), грузовые автомобили (КАМАЗ, ГАЗ, МАЗ и т д). И у каждого из них есть общие свойства: цвет, число_колес, объем_бензобака, и т п.; а кроме этого у них есть и общие методы: набор_скорости, торможение... Правда реализация этих методов для каждого класса будет своя. Но тем не мение как вам перспектива описывать все это для каждого класса, для КАМАЗА описать свойства и методы, для Волги то же самое, аналогично и для других автомобилей? Правда, лень ![]() ![]() Теперь перейдем к нашем DosPaint`у. Всё что мы будем рисовать у нас будет объектами. Каждый из них нам придется описывать. Но смотрите у каждого из объектов будет некоторый набор общих свойств, например, цвет линий, которыми объект будет вычерчен; "начало" объекта (пара координат), для точки, это же будет и "концом", для окружности - это центр её, для линии - один из концов, и т д. Поэтому раз нам всем большой лень ![]()
И снова остановимся. Для чего мы ввели флаг IsShow кто-нибудь догадывается?! Думайте, думайте, я помолчу... Придумали? Правильно, он нам нужен для подпрограмм производящих изменения с объектом, например, изменение цвета (ChangeColor), что будет происходить при вызове этого метода? Ну вопервых будет меняться цвет (переменная Color). А если объект был отображен на экране то тут же его надо и перерисовать, а если мы его есчо не рисовали, то изменим Color молча и больше делать ничего не будем. Вот для того что бы делать есчо чего-нить или не делать кроме непосредственного изменения свойства и служит IsShow. А менять мы его будем в подпрограммых Draw и Hide, котоые выводят и прячут наше изображение соответственно. Ну, все прояснили, начнем реализовывать:
Уфф... Не расслабляться!!! это есчо не все, даже для базового объекта! Давайте предположим, что кто-то (не мы конечно, мы то знаем как наши классы функционируют, и так делать не будем!), создаст в памяти объект (переменную объявит), и тут же воспользуется методом Draw, например, неустанавливая координат и цвета. Что получится? Конечно вы можете сказать что все вновь созданные переменные могут обнулиться, что Color=0; BeginPoint.X=0; BeginPoint.Y=0; IsShow=False... и метод Draw отобразит нам то что мы пытаемся нарисовать, относительно начала координат, черным цветом (Color=0 - черный). Но это ведь неверно, хотя бы цвет-то надо изменить на нормальный! Но наш пользователь этого не знает. Он сразу: раз, и Draw! Что делать? и тут ООП бежит к нам навстречу! Надо просто создать определенный метод, который будет инициализировать наш объект, давая свойствам какие-то первоначальные значения. Такой метод называется конструктором. Он конструирует создаваемый объект. И теперь, прежде чем объект мы будем эксплуатировать так, как нам вздумается он сначала сконструируется, а затем будет нам подвластен! Те классы которые раньше использовали конструкторов не имели, и тем не менее они рабочие, однако для динамических объектов (о них мы поговорим ниже), наличие конструктора чуть ли не обязательное правило для правильного функционирования создваемого объекта. Конструктор, кроме инициализации свойств объекта, занимается важным делом для динамических объектов - он размещает объект в памяти и есчо кое-что делает ![]() Конструкторы и деструкторы отличаются от остальных методов, поэтому для них созданы специальные ключевые слова Constructor и Destructor соответственно, которые используются вместо procedure и function. Именовать конструкторы и деструкторы можно по разному, но лучше, (почти обязательно!), когда конструкторы и деструкторы имеют одинаковые имена, для всех классов, так гораздо понятнее, что это метод - конструктор, а этот - деструктор. Чаще всего конструкторы имеют имя Init(что характерно для Turbo и Borland Pascal`ей или Create - для Delphi), деструкторы - Done(или для Delphi - Destroy) Ну так вот давайте наш класс TBaseGraphObject оснастим конструктором и произведем в нем инициализацию свойств класса:
Теперь пользователь (опять таки если он не вандал ![]() Что думаете с базовым классом покончено? ![]() Это сообщение отредактировал(а) SPrograMMer - 5.5.2005, 20:38 -------------------- животное = зверь законченный гентушник |
||||||
|
|||||||
SPrograMMer |
|
|||
![]() Спамер :) ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 5.11.2004 Где: Краснодар Репутация: нет Всего: 6 |
Люди, как усвояемость? Актуальность темы? Стиль написания?
скажите пожалуйста, а то ведь я еще продолжить могу ![]() -------------------- животное = зверь законченный гентушник |
|||
|
||||
Dr.No_xXx |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 215 Регистрация: 24.2.2005 Репутация: нет Всего: нет |
Очень полезно и познавательно.Можешь продолжать
![]() |
|||
|
||||
Payne |
|
|||
![]() Детектив ![]() Профиль Группа: Участник Сообщений: 247 Регистрация: 6.4.2005 Где: Петербург Репутация: нет Всего: 10 |
Хорошо рассказываешь, и доступно. Продолжай в том же духе
![]() |
|||
|
||||
Fedor |
|
|||
![]() Днепрянин ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2090 Регистрация: 8.2.2003 Где: Великий Репутация: нет Всего: 32 |
Кинешь мне в приват когда закончишь и можно будет в ФАК добавлять.
-------------------- Мы - Днепряне. Мы всех сильней. |
|||
|
||||
SPrograMMer |
|
||||||
![]() Спамер :) ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 5.11.2004 Где: Краснодар Репутация: нет Всего: 6 |
Прежде чем продолжить, отвлекемся еще на нескольк важных моментов при использовании ООП.
1) Размер объекта. Когда мы используем много обычных переменных, например массив записей, каждая из записей, например, содержит три поля - одно числовое (4 байта), второе логическое(1 байт), третья - строка длиной до 255 символов (256 байт). Если в массиве около 200 элементов, то объем памяти, занимаемой такой структурой ~ 51КБ. Довольно много, однако, когда мы используем объекты, то кроме непосредственно данных, в памяти хранятся еще и указатели на методы объекта, таким образом объем объекта с теми же тремя полями (свойствами), у которого есть методы будет занимать больше места в памяти чем только запись с данными => массив объектов, еще более громаден. В DOS нельзя организовывать структуры больше 64К за раз. Хотя "по отдельности" можно организовать довольно большие структуры. Это достигается с применением указателей и использования динамической памяти. Т к любой объект довольно большая структура данных, то использовать непосредственно статические объекты не рекомендуется, лучше создавить объекты по мере нуждаемости в них, и удалять их когда они больше не нужны. 2)Модульное построение программы Группа объектов, точнее классов, которые объявляются программистом решают какую-то часть большой задачи. Даже если задача не сильно большая, может получится так, что часть объектов можно отнести к одной подзадаче, вторую часть - другой. Для реализации методов объектов может потребоваться много строк программного кода. А если еще учесть, что разные классы могут содержать одинаковые методы, в том числе если есть объекты порожденные от одного предка, то для нахождения нужной реализации одного или другого метода одного или нескольких объектов может быть весьмя проблематично. Поэтому часть родственных классов, например базовый класс и его потомков, луче поместить в одном модуле. При этом описание класса (раздел Type) выносится в интерфейсную часть модуля (Interface), а реализация методов - в часть реализации модуля (Implementation). Разбив большуя задачу на подзадачи, каждую из которых решать в отдельном модуле, гораздо проще и легче, чем "пихать" все в одну программу, достигающую несколько десятков тысяч строк. Тем более затем, в случае отладки или доработки найти нужную часть будет проще. Ну программа у нас не глобальных масштабов, поэтому модули мы использовать не будем, а вот насчет указателей и динамической памяти - перестроим (пока не поздно) нашу программу. Для этого много не надо - всего лишь добавить есчо один тип данных - ссылка (указатель) на наш класс:
как видите имя типа-указателя, отличается от имени основного типа лишь заменой буквы T на P, сокращение от имени Pointer - указатель, рекомендую и вам придерживаться того же стиля программирвоания. вот посмотрите как использовать статические объекты:
и динамические:
помните нашего "вандала"-пользователя, который чего хочет то и творит? Если в первом случае, он забудет вызвать конструктор, то получится то, о чем я говорил выше - там где ..."раз и Draw"..., то во втором случае до создания объекта процедурой New, его использовать (объект) не получится, в памяти то его еще нет и работать с ним естественно нельзя. А при выделении памяти объекту можно взывать сразу и конструктор: obj:=New(PBaseGraphObject,Init), таким образом наш пользователь попал в ловушку - неправильно использовать объект в этом случае он просто не в состоянии Это сообщение отредактировал(а) SPrograMMer - 6.5.2005, 18:18 |
||||||
|
|||||||
programs |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 7.9.2005 Где: Оренбург Репутация: нет Всего: нет |
![]() А есть чё нибудь по подробней, а то у меня с объектами проблема! |
|||
|
||||
Romtek |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 7.12.2004 Где: Холон Репутация: нет Всего: 4 |
--------------------
Romiras HomeLab - материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и пр. |
|||
|
||||
Alex |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: нет Всего: 162 |
-------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi" | |
|
Запрещается! 1. Обсуждать и делится взломанными компонентами или программным обеспечением 2. Публиковать ссылки на варез 3. Оффтопить
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, THandle, Rrader, volvo877. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Object Pascal: кроссплатформенные технологии | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |