КАК привить программе классовое сознание?

КАК мне поможет знание объектов?
КАК объявить простейший класс?
КАК и зачем применяется защита данных?
КАК работает конструктор?
КАК применяется ООП в Windows?
КАК строятся крупные ООП программы?
КАК применяется инкапсуляция?
КАК используется полиморфизм?
КАК работает наследование?


КАК мне поможет знание объектов?

До сих пор мы пользовались процедурно-ориентированным методом разработки ПО. То есть мы не оговаривали какой он, просто использовали себе циклы, условия, функции, структуры, совершенно не думая о том, что чего-то не знаем. В настоящее же время почти ни один программист не обходится без объектно-ориентированного программирования или ООП. Дело здесь не в том, что оно модное или в том, что его используют все. ООП очень облегчает разработку, особенно если вы используете готовые классы. Поясню, чем оно отличается.
В литературе очень много говорится о пользе ООП, но все эти их доводы сводятся к тому, что классы использует корпорация Microsoft, значит и мы должны их использовать. Всё это очень хорошо, но читателю наверняка хочется знать, какую они приносят практическую пользу.
Представьте себе фирму, которая разрабатывает и прогрммирует сотовые телефоны - одно из самых перспективных электронных изделий на сегодня. Естественно, что технологии совершенствуются, появляются новые возможности, но от старых наработок никто отказываться не собирается. При процедурном подходе итог был бы следующий - огромное количество библиотечных файлов и исходных текстов. Объём исходников, с которыми придётся работать программисту стремится к гигабайту. Отсюда - информационный бум.
Поэтому, в настоящее время почти в любой фирме, которая разрабатывает ПО (особенно если "с нуля"), принято все новые процедуры и функции объединять в классы. Для каждого нового проекта этой используются уже существующие наработки и создаются новые.
Класс упорядочивает данные по смыслу. Например класс для работы с меню, класс для принтера, класс для работы с файлами. На деле часто создаются классы для работы со специфическими электронными устройствами (жидкокристаллические дисплей, клавиатура, считывающие устройства). Важно понять - в классе собираются функции для описания какого-то одного объекта. Все они тесно связаны по смыслу. Причём в отличие от структуры, класс объединяет не только данные, но и методы работы с ними, представленные в виде функций-членов этого класса. Например, класс для работы с графикой содержит основные графические функции: овалы, прямоугольники, линии, а функции для работы с меню содержатся в другом классе.

КАК объявить простейший класс?

Выглядеть это будет так:

class Graph {

public:
void DrawOval(int,int,int,int);
void DrawLine(int,int);
void DrawRect(int,int,int,int);

}

Не правда ли, похоже на объявление структуры (struct)? Только в структуру нельзя поместить функции, а в класс можно. Мы объединяем объявления функций в класс. Слово public говорит о том, что эти функции доступны для применения. Определить функции, объявленные в классе, мы можем так:

//Определение функции рисования линии
void Graph::DrawLine(int x, int y)
{
//здесь будет текст тела функции-члена класса
}


//Функция рисования прямоугольника определяется аналогично:
void Graph::DrawRect(int x, int y, int w, int h)
{
//тело функции

}

Сначала указывается тип функции: void, int ,float, а потом имя класса, от которого порождена функция. Затем ставятся два двоеточия и указывается имя функции, её аругменты.


Разрабатывая ПО для себя, проще всего сделать его как быстрее. Но в фирме незаменимых людей нет. Программисты приходят и уходят. Не будет же каждый новый программист начинать всё заново и создавать новые классы! Ему скорее всего дадут время на ознакомление с классами, написанными его предшественником. В этом смылсе ООП идеально подходит для того, чтобы разбираться в в чужом коде. Даже чужие классы всегда выглядят стройно и слажено. По крайней мере в них можно разобраться.

КАК и зачем применяется защита данных?

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

Для того, чтобы такого не случалось, применяются защищённые данные. Они размещаются в поле protected. Суть их в том, что задать значения этим переменным и даже прочитать их значение могут только функции того же класса, в котором они размещены. Никаким другим образом вы не сможете ни менять их значения, ни считывать их соедржимое. И если не предусмотреть соответствующие функции Get и Set, данные окажутся совсем недоступными.
Вот пример:

class Control {

//Защищённые данные
protected:
int Speed; //Скорость порта
int Protocol; //Протокол обмена данными
...

public:
Control(); //Конструктор класса
int GetSpeed() { return Speed; }; //Функция возвращает значение переменной Speed
void SetSpeed(int); //задаёт значение скорости

int GetProtoc() { return Protocol; } //Возвращает значение протокола
void SetProtoc(int); //Задаёт проткол обмена
} ;

Обратите внимание, что тело функции можно определить как в теле класса, так и вне его. В этом примере функции GetSpeed() и GetProtocol() опеределны прямо в классе.

Теперь посмотрите сюда. Я хочу использовать значение защищённой переменной Speed.

Control CTRL; //создаём объект класса


cout<<"Скорость передачи = "<<CTRL.Speed;

Такая конструкиця работать не будет. Компилятор выдаст ошибку и скажет, что параметр Speed не доступен, хотя мы попытались всего лишь его прочитать.
Если же мы напишем так:

cout<<"Скорость передачи = "<<CTRL.GetSpeed();

Мы узнаем, какая у нас скорость. Обратите внимание, что все функции - члены класса и все перменные класса в теле программы вызываются так же, как и для структуры struct, через тэги. Мы объявляем объект класса:

Control CTRL;

И только через него сможем работать с данными:

CTRL.SetProtoc(UDP);

Но вы можете резонно спросить: А как защищённые переменны-члены классов получают изначально свои значения? Ведь их значения реально используются программой, значит они должны откуда-то браться. По сути эти значения должны быть записаны в переменные ещё до того, как программа к ним обратится. Для этой цели служит конструктор.

КАК работает конструктор?

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

Control::Control()
{
Speed=19200;
Protocol = TCPIP;

}

Имейтие в виду: имя конструктора всегда совпадает с именем класса!

В своё время, большинство программистов, привыкших к процедурному языку, очень неохотно расставались со своими идеалами. Зато теперь есть настолько объектно-ориентированные языки, что в них для того, чтобы что-то создать, нужно объявлять класс. Все функции в таких языках - изначально функции-члены (методы) главного класса, который одновременно является ещё и телом программы. Примером могут служить языки: Java и Smalltalk.

КАК работает ООП в Windows?

Библиотеки классов MFC, OWL, VCL - обладают многочисленными классами элементов управления: диалоговых окон, списков, кнопок, и других компонентов пользовательского интерфейса. Чтобы разместить в вашем окне прокручиваемый список, нужно создать экземпляр класса СComboBox, после чего, вы с помощью тэга, будете по-одному выуживать из него методы: добавить в список, удалить из списка, очистить список и т.д.

//Создавая свою программу My, мы порождаем свой класс-наследник от класса
//диалоговых окон CDialog

class CMyDlg : public CDialog
{
// Конструктор
public:
CMyDlg(NULL); // стандартный конструктор

// Данные
//....

CComboBox m_Combo1; //создаём переменную-член (variable-member) класса CComboBox

}


//...здесь будет какой-то код

//Добавить новое значение в прокручиваемый список

m_Combo1.AddString("Новая строка");

Это был пример использования ООП библиотеки MFC.

КАК строятся крупные ООП проекты?

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

Инкапсуляция - это защита данных. Если мы поставим вместо слова publc - слово protected, то эти данные будут доступны только для членов класса, а если private, доступ к ним будет ограничен. Примеры защиты данных мы с вами уже разбирали выше. Так, что вы знаете, что это такое.

Полиморфизм - возможность применять функции с одинаковыми именами, но с разным количеством аргументов и входящие в разные классы. Использоваться будет именно тот метод, к которому произошло обращение. Это нужно тогда, когда мы не хотим менять имя функции, а типы в ней используются разные. Создавая несколько функций с одним именем, но с разными типами данных и разным количеством аргументов, мы не будем волноваться, что компилятор ошибётся и запустит не ту функцию.

Наследование - порождение от родительского класса - классов-наследников, которые будут использовать некоторые свойства класса родителя. Так в библиотеке классов MFC главным считается класс CObject, от которого порождён класс CCmdTarget, обрабатывающий сообщения. В свою очередь от него порождён класс окна, от которого порождены соответствующие классы: панели управления, диалоги, кнопки, флажки и др. более мелкие классы. Получается, что чем выше класс, тем более он абстрактен. Чем ниже - тем более детален и конкретен. Абстаркция в ООП - это целая философия. И в предыдущем примере, мы порождали свой класс CMyDialog от стандартного класса MFC CDialog.


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

При создании программы под Windows, мы будем автоматически создавать и класс окна этой программы и все действия с ним - нажатие кнопок, выбор меню, отметка флажков, клавиши клавиатуры, взаимодействие с мышью и др. - всё это будут методы этого класса. Поэтому, не будем сейчас подробно останавливаться на ООП.


Если вы что-то не поняли в этой главе, не огорчайтесь. В разделе Windows мы будем много ещё об этом говорить.

Очень подробно все преимущества ООП описываются в книге Х.М. Дейтел "Как программировать на С++".

Назад Содержание Вперёд