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

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

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

2020-06-04 199
ООП сам по себе запрещает работать с объектами напрямую, т.е. взаимодействие с ними осуществимо только с помощью методов. А внутренняя реализация самого объекта должна быть скрыта. 0.00 из 5.00 0 оценок
Заказать работу

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

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

Основные понятия ООП

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

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

Основные понятия ООП:

    1. инкапсуляция;
    2. наследование;
    3. полиморфизм.

Более подробно они были рассмотрены ранее, поэтому в этой лекции мы пройдёмся по ним очень кратко.

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

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

Под полиморфизмом понимается возможность использования методов, имеющих одинаковые идентификаторы, но разную реализацию.

Принцип декомпозиции и абстракции

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

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

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

Классы

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

Синтаксис объявления класса в C++ имеет следующий вид:

class <name>{ <mode>: /*список свойств и методов*/ };

Здесь: name – идентификатор класса, а mode описывает спецификаторы доступа. В C++ существует 3 спецификатора доступа: private, protected, public. В случае использования первого спецификатора доступа список свойств и методов, указанный после двоеточия будет доступен для использования исключительно в рамках него. В случае использования второго спецификатора доступа список свойств и методов, указанных после двоеточия, будет доступен в рамках иерархии наследования. В случае же использования третьего спецификатора доступа, список свойств и методов, указанных после двоеточия будет доступен для использования всеми функциями и объектами, которые могут не входить класс.

При объявлении класса не обязательно использовать сразу три спецификатора и не обязательно указывать их в таком порядке.

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

Пример 1. Объявление класса с одним методом и его использование. #include <iostream> using namespace std; class Example{ public: void msg(string str){ cout << str << endl; } }; int main(){ Example exp; string str; cin >> str; exp.msg(str); return 0; }

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

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

Классы. Пример.

Задача: создать класс, моделирующий игрока в компьютерной игре.

Шаг 1. Определиться со свойствами.

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

Шаг 2. Определиться с методами.

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

Таким образом, мы определили поля и методы нашего класса, а теперь опишем сам класс (шаг 3):

Пример 3. Реализация класса для поставленной задачи. class Player{ private: string name; float maxHealth, currentLvlOfHealth; int impactForce; bool presenceOfWeapins; int numberOfPoints; public: void setName(){ cout << “Enter your name: ” cin >> name; } void setPresenceWeapons(bool pW){ presenceOfWeapins = pW; } void addPoints(int num){ numberOfPoints += num; } void addHealth(float num){ if (currentLvlOfHealth!= maxHealth) currentLvlOfHealth += num; } void subHealth(float num){ if (currentLvlOfHealth >=0) currentLvlOfHealth -= num; } float getHealth(){ return currentLvlOfHealth; } int getPoints(){ return numberOfPoints; } bool getPOW(){ return presenceOfWeapins; } string getName(){ return name; } void draw(int x, int y, int dx, int dy, int position); void setMaxHealth(float mH){ maxHealth = mH; } };

В полученном классе содержится 6 скрытых полей. Из них можно получить значения только четырёх с помощью методов getHealth(), getPoints(), getPOW() и getName(). Таким образом, все методы класса имеют непосредственный доступ ко всем его скрытым полям.

Также в классе существует одно объявление метода. Соответственно, в таком случае этот метод должен быть определён за пределами класса, однако для этого должна быть использована операция доступа к области видимости.

Пример 4. Формат определения метода класса за его пределами с помощью операции «::». void Player:: draw(int x, int y, int dx, int dy, int position){ /*Тело объявленного в функции метода*/ }
Пример 5. Формат определения метода класса за его пределами с помощью inline. inline void draw(int x, int y, int dx, int dy int position){ /*Тело объявленного в функции метода*/ }

Оптимизация примера

Класс, который был создан ранее может быть оптимизирован, а количество методов в нём может быть немного сокращено. Сделать это можно с помощью объединения методов subHealth (float num) и addHealth (float num). В обоих методах не осуществляется проверка на передачу в качестве параметра отрицательного числа. А ведь если передать такой параметр, то в первом случае количество здоровья игрока будет не уменьшено, а увеличено, а во втором, наоборот уменьшено. Поэтому можно создать один метод с названием, например changeHealth (float num), который также будет принимать число, на которое нужно изменить уровень текущего здоровья игрока.

Таким образом, этот метод может выглядеть следующим образом:

Пример 6. void changeHealth(float num){ if (((num < 0) and (currentLvlOfHealth > 0)) or ((num > 0) and (currentLvlOfHealth < maxHealth))) currentLvlOfHealth += num; }

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

Назначение конструктораинициализация объекта.

Автоматический вызов конструктора позволяет избежать ошибок, связанных с использованием неинициализированных переменных.

Описание объектов

Ранее было разобрано то, что объекты, созданные на основе одного класса, называются экземплярами класса. Иными словами, конкретная переменная типа «класс» и есть экземпляр класса или объект. Время жизни и видимость объектов напрямую зависит от того в каком месте программы она была описана и полностью подчиняется общим правилам языка программирования C++.

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

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

Опираясь на пример, рассмотренный ранее создадим экземпляры класса Player.

Пример 7. Создание экземпляра класса. Player myPlayer; /*объект myPlayer с параметрами по умолчанию*/ Player masPlayer[21]; /*массив объектов с параметрами по умолчанию*/ Player *ptrPlayer = new Player; /*динамический объект*/ Player &player = myPlayer; /*ссылка на объект*/

При создании объекта его можно объявить константой. Такой объект отличается от обычных тем, что изменение значений его полей строго запрещено. Важно то, что к константным объектам должны применяться исключительно константные методы.

Как правило, в качестве константных описываются те методы, которые позволяют получить значение какого-либо поля.

Классы. Указатели.

Указатель this

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

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

Применить указатель this можно и в явном виде, однако используется в основном для возвращения указателя или ссылки на объект, вызвавший метод.

Чтобы получить указатель в операторе return достаточно указать идентификатор this, если же нужно вернуть ссылку, то необходимо использовать операцию «*». Также этот указатель применяется для идентификации поля класса в том случае, если его идентификатор совпадает с идентификатором формального параметра метода.

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

Пример 8. Создание метода, возвращающего указатель на экземпляр класса. <…> Player & deceasedPlayer(Player &Pl){ if(Pl.currentLvlOfHealth <= 0) return this; }

В языке программирования Pascal вы рассматривали self -параметр, аналогом которого является указатель this в С++.

Статические методы

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

Обращение к таким методам не отличается от способов обращения к статическим полям. Т.е. либо с использованием идентификатора класса и оператора «::», либо с использованием идентификатора экземпляра этого класса.

Пример 14. Статические методы. <…> class Numeric{ private: static float num; public: static float getNum(){ return num; } static void setNum(float sNum){ num = sNum; } }; <…> int main(){ Numeric myNum; myNum.setNum(16); cout << myNum.getNum(); return 0; }

Дружественные классы

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

Для реализации такого варианта необходимо указать в одном классе дружественность к другому классу в формате:

friend class идентификатор_класса;

Для примера создадим 2 класса Values и Display. После чего сделаем класс Display другом класса Values.

Пример 16. Дружественные классы. #incluse <iostream> using namespace std; class Values{ private: long intValue; long double lDoubleValue; public: friend class Display; }; class Display{ private: bool isDisplay; public: void displayItem(Values &value){ if (isDisplay) cout << “int value - ” << value.intValue << endl << “long double value - ” << value.lDoubleValue; else cout << “Error: isDisplay = false”; } }; <…> int main(){ Values value(169, 3.14); Display display(true); display. displayItem(value); return 0; }

Объявление friend не является спецификатором доступа и не наследуется.

Класс сам определяет, какие функции и классы являются дружественными, а какие нет!!!

Отличия структур и объединений от классов

Структуры ( struct ) и объединения ( union ) представляют собой частные случаи классов!!!

Структуры отличаются от классов тем, что доступ к элементам, а также базовый класс при наследовании по умолчанию считаются public. Их предпочтительнее использовать для классов, все элементы которых доступны.

Если говорить об объединениях, то они отличаются от классов тем что:

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

 

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

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

Основные понятия ООП

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

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

Основные понятия ООП:

    1. инкапсуляция;
    2. наследование;
    3. полиморфизм.

Более подробно они были рассмотрены ранее, поэтому в этой лекции мы пройдёмся по ним очень кратко.

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

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

Под полиморфизмом понимается возможность использования методов, имеющих одинаковые идентификаторы, но разную реализацию.


Поделиться с друзьями:

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...

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

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



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.049 с.