Лекция 01 — Основы ООП


Чтобы посмотреть презентацию с картинками, оформлением и слайдами, скачайте ее файл и откройте в PowerPoint на своем компьютере.
Текстовое содержимое слайдов презентации:

Объектно-ориентированное программирование Парадигма программирования, основанная на представлении предметной области в виде взаимосвязанных абстрактных объектов и их реализаций Классы и объекты В ООП вводится понятие Класса – пользовательского типа данных, объединяющего данные и методы их обработкиОбъектом называется экземпляр классаСобака – это классСобака Жучка из 3 подъезда – это объект, представитель или экземпляр класса «Собака» class <Имя класса>{// поля класса (данные и методы)}; Данные объекта (переменные объекта, члены-данные) Члены-данные (data members) хранят всю необходимую информацию об объекте, формируют его состояние, характеристики и т.п.Изменение состояния объекта или его характеристик связано с изменением данных, в нем содержащихся Методы класса Класс может содержать один или более методов, позволяющих осуществлять манипуляцию данными объектаМетод объекта – программный код, выполненный в виде процедуры или функции, реагирующий на передачу объекту определенного сообщенияВызов метода объекта может приводить к изменению его состояния (значение членов-данных), а может и не приводитьПример 1: поиск и замена текста в документеПример 2: проверка правописания текста документа Свойства Свойство – составляющая часть объекта, доступ к которой осуществляется программистом как к переменной объектаВ некоторых объектно-ориентированных языках программирования (например, в C++ и Java) свойства, как элемент языка, отсутствуютВ этом случае в класс добавляют методы, посредством которых осуществляется доступ к необходимым переменным класса Пример: Треугольник СвойстваКоординаты вершины AКоординаты вершины BКоординаты вершины CПлощадьПериметрКоординаты центра вписанной окружностиМетодыПереместить в заданном направленииОтмасштабироватьПовернуть вокруг заданной точки class Point { public: double x, y; }; class Triangle { public: double GetArea(); double GetPerimeter(); Point GetCenter(); void Move(double dx, double dy); void Scale(double sx, double sy); void Rotate(Point center, double angle); Point p0, p1, p2; }; Важнейшие принципы ООП Абстракция данныхИнкапсуляцияНаследованиеПолиморфизм Абстракция данных Объекты представляют неполную информацию о реальных сущностях предметной областиАбстракция позволяет оперировать с объектном на уровне, адекватном решаемой задачеВысокоуровневые обращения к объекту могут обрабатываться с помощью вызова функций и методов низкого уровня Инкапсуляция Инкапсуляция - способность объекта скрывать внутреннее устройство своих свойств и методовСогласно данному принципу, класс должен рассматриваться как черный ящикВнешний пользователь не знает детали реализации объекта и работает с ним только путем предоставленного объектом интерфейсаСледование данному принципу может уменьшить число связей между классами и упростить их независимую реализацию, модификацию и тестирование class IntStack{public:void Push(int value);int Pop();bool IsEmpty()const;private:// здесь располагаются данные// необходимые для реализации стека целых чисел}; Наследование Наследование позволяет описать новый класс на основе уже существующего родительского (базового) классаКласс-потомок может добавить свои собственные свойства и методы, пользоваться методами и свойствами базового классаНаследование позволяет строить иерархии классов class Plane { public: void TakeOff(); void Fly(); void Land(); private: double m_fuel; }; class MilitaryPlane : public Plane { public: void Attack(); private: int m_ammo; }; Полиморфизм Полиморфизмом называют явление, при котором классы-потомки могут изменять реализацию метода класса-предка, сохраняя его интерфейсПолиморфизм позволяет обрабатывать объекты классов-потомков как однотипные объекты, не смотря на то, что реализация методов у них может различаться class Shape { public: virtual double GetArea()=0; }; class Rectangle : public Shape { public: virtual double GetArea() { return width * height; } private: double width, height; }; class Circle : public Shape { public: virtual double GetArea() { return 3.1415927 * radius * radius; } private: double radius; }; Объявление класса в C++ Для объявления класса в C++ служит ключевое слово classСинтаксисclass идентификатор{ // объявление данных и методов};Реализация методов класса может быть вынесена за пределы объявления класса Пример class Date{int year, month, day;void next();void print();};// Реализация методов классаvoid Date::print(){printf(“%d/%d/%d”, day, month, year);}void Date::next(){// ...} Размещение классов в различных файлах Общепринятой практикой является размещение объявления классов в заголовочных файлах .h, а их реализации – в файлах .cppПовышение модульности проектаКаждый класс может быть подключен для дальнейшего использования при помощи директивы #include “имя заголовочного файла”При внесении изменений в реализацию метода класса перекомпиляции подвергнутся только измененные файлы date.h class Date { public: void Next(); void Print(); private: int m_day; int m_month; int m_year; }; date.cpp#include “date.h”void Date::Next(){// ...}void Date::Print(){// ...} main.cpp#include “date.h”int main(){Date date1;return 0;} Ограничение доступа к данным и методам класса Доступ к данным и методам класса извне может быть ограниченРекомендуется запрещать доступ к данным класса в обход его методовДля разделения прав доступа к полям класса используются ключевые словаpublic:private:protected: Публичные (public) поля класса Public-методы и данные класса определяют его интерфейсдоступ к ним возможен из любой части коданеобходимо помещать в public-раздел класса только необходимый набор методов, выполняющих высокоуровневые операции над объектом класса Закрытые (частные) поля класса Private-данные и методы класса определяют его реализациюДоступ к ним разрешен только из методов данного классаРекомендуется все данные класса делать закрытыми, их обработку осуществлять внутри методовЗакрытые методы класса обычно используются публичными методами, решая внутренние задачи класса Защищенные поля класса Protected-данные и методы определяют интерфейс для производных классовДоступ к ним разрешен изнутри методов данного класса и всех его потомковВ защищенной зоне размещают методы, которые не должны быть видны снаружи класса, но реализация которых может быть переопределена или использована производными классами class Date{public:void Next();void Print();private:int year, month, day;};// Реализация методов классаvoid Date::Print(){printf(“%d/%d/%d”, day, month, year);}void Date::Next(){// ...} Ссылка на себя Внутри методов класса для обращения к данным класса можно использовать их именаВ метод класса неявно передается указатель на объект, для которого он вызываетсяДоступен данный указатель по ключевому слову this class ListItem { public: void Append(ListItem *pItem) { pItem->m_pNext = this; m_pPrevious = pItem; m_pNext = NULL; } private: ListItem *m_pNext; ListItem *m_pPrevious; int m_data; }; Константные методы В языке C++ методы объекта, не изменяющие его состояния (его данных) могут быть объявлены константнымиНапример, методы, возвращающие значения определенных полей данныхИзменить данные класса из константного метода нельзя Когда возникает необходимость в константных методах Если объект был объявлен как константа, либо доступен по константной ссылке или указателю на const, то вызвать у него можно только константные методыЭто заставляет объявлять методы константными везде, где это только возможно class IntArray{public:…int GetSize()const{return m_numberOfItems;}void ClearElements(){delete [] m_pData;m_pData = NULL;m_numberOfItems = 0;}private:int *m_pData;int m_numberOfItems;};void f(IntArray const& array){int i = array.GetSize();// можноarray.ClearElements();// нельзя – неконстантные методы недоступны} Изменчивые (mutable) данные класса Данные класса, которые все-таки нужно изменять из константных методов класса в С++ объявляются с ключевым словом mutableПользоваться этой возможностью следует аккуратно, четко осознавая, что даже в этом случае константные методы не должны изменять состояние объектаПод состоянием объекта здесь понимается информация о нем, доступная посредством публичных методов class VeryComplexShape{public:VeryComplexShape(){m_areaInitialized = false;}double GetArea()const{if (!m_areaInitialized){// вычисляем площадь фигуры (задача требует длительных вычислений)m_areaInitialized = true;…}return m_area;}void ModifyShape(...){m_areaInitialized = false;// ...}private:mutable bool m_areaInitialized;mutable double m_area;}; Инициализация экземпляра класса Для инициализации состояния объекта в момент его создания существует специальная функция – конструкторКонструктор имеет то же имя, что и имя классаТип возвращаемого значения для конструктора не указывается (даже void)Конструктор вызывается в момент создания экземпляра класса (объявление переменной класса или вызов оператора new)Класс может иметь несколько конструкторов, предоставляющих различные способы инициализации объекта class Date { public: Date(int day, int month) { m_day = day; m_month = month; m_year = GetCurrentYear(); } Date(int day, int month, int year) { m_day = day; m_month = month; m_year = year; } private: int m_day, m_month, m_year; }; Конструктор по умолчанию Конструктор, не имеющий параметров, называется конструктором по умолчаниюПоля данных в таком конструкторе инициализируются значениями по умолчаниюСоздавать такой конструктор или не создавать – зависит от конкретной задачи Инициализация данных экземпляра класса В качестве данных класса могут выступать другие классыИх инициализация осуществляется ДО выполнения тела конструктораДля их инициализации вызываются конструкторы по умолчаниюЕсли таковых не имеется, программист должен использовать списки инициализации Списки инициализации Применяются для инициализации полей класса в конструкторе ДО выполнения его телаИспользование списков инициализации – единственное решение в случае, когда класс содержит внутри себяполя, являющиеся классами без конструкторов по умолчаниюконстантыссылки class Foo { public: Foo(int i, int j = 0) :m_i(i) ,m_j(j) { } private: int m_i, m_j; }; class Bar { public: Bar() :m_foo(3, 5) { } Bar(int i, int j) :m_foo(i, j) { } private: Foo m_foo; }; Деинициализация экземпляра класса В ходе своей работы объект может использовать определенные системные ресурсыДинамическая память, открытые файлы, сетевые соединения и т.п.Для освобождения этих ресурсов служит особый метод класса – деструкторИмя деструктора совпадает с именем класса, только перед ним указывается символ ~ (тильда)Данная функция вызывается автоматически при уничтожении экземпляра класса:Выход за пределы блока, в котором объявлен экземпляр классаВызов оператора delete или delete [] class MyFile{public:MyFile():m_pFile(NULL){}~MyFile(){Close();}bool Open(const char *fileName){Close();m_pFile = fopen(fileName, “r”);return m_pFile != NULL;}void Close(){if (m_pFile){fclose(m_pFile); m_pFile = NULL;}}private:FILE *m_pFile;}; Конструктор копирования (копирующий конструктор) В языке C++ существует специальный тип конструкторов, использующийся для создания копии объектаЯвное создание копии объекта программистомНеявное создание копии объектаВозврат объекта из функцииПередача объекта в функцию по значениюВо время работы механизма исключенийСинтаксисType(Type const& t); Автоматически сгенерированный конструктор копирования Если программист не определит конструктор копирования явно, компилятор сгенерирует его во время компиляцииАвтоматически сгенерированный конструктор копирования осуществляет копирование всех полей класса, вызывая для них их конструкторы копирования #include "stdio.h" class Foo { public: Foo():m_moo(0) { } Foo(Foo const& foo) :m_moo(foo.m_moo) { printf("Creating copy of foo\n"); } private: int m_moo; }; class Bar { public: void Do() { printf("Do\n"); } private: Foo m_foo; }; void f(Bar b) { printf("f()\n"); b.Do(); } Bar g() { printf("g()\n"); Bar b; return b; } int main() { Bar b0; printf("Call f()\n"); f(b0); printf("Call g()\n"); Bar b1 = (g()); b1.Do(); return 0; } OUTPUT: Call f() Creating copy of foo f() Do Call g() g() Creating copy of foo Do Создание собственного конструктора копирования Часто возникают ситуации, когда автоматически сгенерированный конструктор копирования не подходитПример – класс, реализующий массивСтандартный конструктор копирования просто скопирует значение указателя на элементы массива, в то время как необходимо выделить в динамической памяти новый массив и скопировать в него данные из оригинального массиваВ этом случае программист должен разработать собственный конструктор копирования #include "stdio.h" #include "memory.h" class IntArray { public: IntArray():m_pData(NULL), m_size(0){} IntArray(IntArray const& arr) :m_pData(new int [arr.m_size]) ,m_size(arr.m_size) { if (m_size != 0) { memcpy(m_pData, arr.m_pData, sizeof(int) * m_size); } } private: int * m_pData; int m_size; }; Запрещение копирования объектов Возможны ситуации, когда операция копирования объекта не имеет смысла и должна быть запрещенаКласс, инкапсулирующий сетевое соединениеКласс, инкапсулирующий работу с файломОбъект должен существовать в единственном экземпляре внутри приложения, например, «клавиатура»Для запрещения копирования объекта, конструктор копирования объявляется в закрытой (private) области классаРеализацию данного конструктора можно не писать class CFile{public:// …private:CFile(Cfile const&);// …};

Приложенные файлы

  • ppt 851192
    Размер файла: 736 kB Загрузок: 4

Добавить комментарий