Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Уровни доступа к членам класса




Абстракция данных

Абстрагирование означает выделение значимой информации и исключение из рассмотрения незначимой. В ООП рассматривают лишь абстракцию данных (нередко называя её просто «абстракцией»), подразумевая набор значимых характеристик объекта, доступный остальной программе.

Инкапсуляция

Инкапсуляция — свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе. Одни языки (например, С++, Java или Ruby) отождествляют инкапсуляцию с сокрытием, но другие (Smalltalk, Eiffel, OCaml) различают эти понятия.

Наследование

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

Полиморфизм подтипов

Полиморфизм подтипов (в ООП называемый просто «полиморфизмом») — свойство системы, позволяющее использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта. Другой вид полиморфизма — параметрический — в ООП называют обобщённым программированием.

Класс

Класс — универсальный, комплексный тип данных, состоящий из тематически единого набора «полей» (переменных более элементарных типов) и «методов» (функций для работы с этими полями), то есть он является моделью информационной сущности с внутренним и внешним интерфейсами для оперирования своим содержимым (значениями полей). В частности, в классах широко используются специальные блоки из одного или чаще двух спаренных методов, отвечающих за элементарные операции с определенным полем (интерфейс присваивания и считывания значения), которые имитируют непосредственный доступ к полю. Эти блоки называются «свойствами» и почти совпадают по конкретному имени со своим полем (например, имя поля может начинаться со строчной, а имя свойства — с заглавной буквы). Другим проявлением интерфейсной природы класса является то, что при копировании соответствующей переменной через присваивание, копируется только интерфейс, но не сами данные, то есть класс — ссылочный тип данных. Переменная-объект, относящаяся к заданному классом типу, называется экземпляром этого класса. При этом в некоторых исполняющих системах класс также может представляться некоторым объектом при выполнении программы посредством динамической идентификации типа данных. Обычно классы разрабатывают таким образом, чтобы обеспечить отвечающие природе объекта и решаемой задаче целостность данных объекта, а также удобный и простой интерфейс. В свою очередь, целостность предметной области объектов и их интерфейсов, а также удобство их проектирования, обеспечивается наследованием.

Объект

Сущность в адресном пространстве вычислительной системы, появляющаяся при создании экземпляра класса (например, после запуска результатов компиляции и связыванияисходного кода на выполнение).

 

Другое обьяснение ООП с примерами

Объектно-ориентированное программирование (ООП) в C++

Опубликовано 17.05.2012 22:32 пользователем admin

Объектно-ориентированное программирование (ООП) — подход к программированию, при котором основными концепциями являются понятия объектов и классов.

Класс — это определяемый разработчиком тип данных.

Тип данных характеризуется:

  1. Способом хранения и представления этих данных.
  2. Назначением этих данных (профилем их использование).
  3. Набором действий, которые над этими данными могут производится.

Например, тип int предназначен для хранения целых чисел и подразумевает ряд операция над ними (+,-,*,/,% и пр.).

Класс — это тип, описывающий устройство объектов, их поведение и способ представления.

Объект — сущность обладающая определённым поведением и способом представления, т. е. относящееся к классу (говорят, что объект — это экземпляр класса, если он к нему относится).

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

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

Описание класса состоит из полей и методов.

Поля (или свойства, в рамках C++ это можно считать синонимом) описывают то, какие данные смогут хранить экземпляры класса (т.е. объекты). Конкретные значения сохраняются уже внутри объектов. Поля объявляются в теле класса.

К полям внутри класса можно обращаться непосредственно по именам полей.

Методы класса — это функции, которые смогут применяться к экземплярам класса. Грубо говоря, метод — это функция объявленная внутри класса и предназначенная для работы с его объектами.

Методы объявляются в теле класса. Описываться могут там же, но могут и за пределами класса (внутри класса в таком случае достаточно представить прототип метода, а за пределами класса определять метод поставив перед его именем — имя класса и оператор ::).

Методы и поля входящие в состав класса называются членами класса. При этом методы часто называют функциями-членами класса.

Пример:

classComplex {doubleimg;doublereal;};

В примере описан класс Complex с двумя полями img и real.

Абстракция данных

Абстракция данных — это выделение существенных характеристик объекта, которые отличают его от прочих объектов, четко определяя его границы.

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

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

Вес, размер и положение — это поля будущего объекта-контейнера.

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

Ключевые черты ООП

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

Уровни доступа к членам класса

По уровню доступа все члены класса делятся на открытые (public), закрытые (private) и защищённые(protected).

Перед объявлением членов внутри класса ставятся соответствующие ключевые слова. Если такое слово не поставлено, то считается, что член объявлен с уровнем private. В примере выше класса Complex, соответственно, оба поля имеют уровень доступа private.

Члены объявленные как private доступны только внутри класса.

Члены объявленные как protected доступны внутри класса и внутри всех его потомков.

Члены объявленные как public доступны как внутри, так вне класса (в том числе в потомках).

Доступность членов класса в зависимости от уровня доступа private protected public
Внутри класса + + +
Внутри потомка класса - + +
В несвязанной с классом части программы - - +

Методы объявленные в открытой части класса называются его интерфейсом

Пример объявления различных уровней доступа:

classComplex {private: // Закрытая часть класса, её элементы доступны только внутри классаdoubleimg;public: // Открытая часть класса, её элементы доступны вездеdoublereal;doublegetImg() { // Через этот метод мы сможем получить значение закрытого поляreturnimg; // Поле закрытое, но метод открытый };};

Интерфейс класса

Все методы класса, находящиеся в его открытой части (с уровнем доступа public) называют интерфейсом класса

Интерфейс предназначен для взаимодействия класса с остальной программой. Зная методы интерфейса и их назначение можно использовать класс, не вникая в его внутреннее устройство. Соответственно, интерфейс реализует принцип инкапсуляции.

Конструктор и деструктор

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

Конструктор имеет такое же имя, как и сам класс.

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

Каждый раз, когда ваша программа создает объект, C++ вызывает конструктор класса, если подходящий (с соответствующими параметрами) конструктор существует.

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


Конструктор по умолчанию

Конструктор по умолчанию — это конструктор без параметров.

Если он не задан явно и при этом не создано других конструкторов с параметрами, то конструктор по умолчанию создастся автоматически. При этом все свойства нового объекта не будут никак проинициализрованы (получат «мусорные» значения из памяти).

Пример:

classComplex {private: // Закрытая часть классаdoublereal; // Поле, действительная частьdoubleimg; // Поле, мнимая частьpublic: // Открытая часть классаvoidprintComplex() { // Этот метод мы сможем вызывать за приделами классаcout&lt< real &lt< " + " &lt<img&lt< 'i' &lt<endl; // Выводимполя}}; intmain() {Complex a; // Работает конструктор по умолчанию,Complex b; // поля получают мусорные значенияa.printComplex(); // Выводим первый и второй объектыb.printComplex(); // с помощью созданного метода printComplex()return 0;}

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

Пример класса с двумя конструкторами (первый из них — без параметров):

class Complex { private:   double real; // Действительнаячасть     double img; // Мнимаячасть public:Complex() {       real = 0;img = 0;   }Complex(double a, double b) {       real = a;img = b;   }   void printComplex() {cout&lt< real &lt< " + " &lt<img&lt< 'i' &lt<endl;   }}; intmain() { Complex a; Complex b(3.14, 2.71);a.printComplex();b.printComplex(); return 0;}

При создании объекта мы должны либо в круглых скобках указать параметры, чтобы заработал нужный конструктор (как для объекта b), либо не указывать ничего, чтобы использовался конструктор по умолчанию (как для объекта a).

Копирующий конструктор

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

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

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

Пример:

class Complex { private:   double real; // Действительнаячасть   double img; // Мнимаячасть public:Complex() {       real = 0;img = 0;   }Complex(const Complex& c) { // Копирующийконструктор       real = c.real;img = c.img;   }Complex(double a, double b) {       real = a;img = b;   }   void printComplex() {cout&lt< real &lt< " + " &lt<img&lt< 'i' &lt<endl;   }}; intmain() { Complex b(3.14, 2.71); Complex d(b);d.printComplex();return 0;}

Копирующий конструктор создаётся по умолчанию, если не задан явно. В поля нового объекта он копирует значения соответствующих полей объекта-аргумента.

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

Деструктор

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

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

Деструктор имеет такое же имя, как и класс, но с символом тильды (~) в качестве префикса. Например, в классе Complex деструктор имеет имя ~Complex().

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

Наследование

Пример наследования:

// Класс товаров в некотором магазинеclass ShopItem {          public:                          char    model[100]; // модель                          char    brand[100]; // производитель                          double price; // цена};// Мобильныетелефоны — наследникклассатоваровclass MobilePhone : public ShopItem {                   public:                          char    phoneColor[100]; // цвет                          int      batteryLife; // времяработыотбатареивчасах};// Картыпамяти — наследникклассатоваровclass MemoryCard : public ShopItem {                   public:                          char    formFactor[100]; // формат карточки памяти};// Смартфоны — наследник класса мобильных телефоновclass SmartPhone : public MobilePhone {               public:                          char    os[100]; // операционная система};

Когда объявляется класс-наследник, то сразу после его имени ставится двоеточие и указывается уровень (или способ) наследования (public, private, protected), а затем имя класса родителя. Уже потом открывается блок с описанием класс-наследника.

Private-наследование

Те члены, что в родителе были protected и public, становятся private в потомке.

Protected-наследование

Те члены, что в родители были protected и public становятся protected в потомке. Такой вариант используется редко.

Public-наследование

Те члены, что в родители были protected и public, остаются, соответственно, protected и public в наследнике, сохраняя свой уровень доступа.

Если уровень явно не указан, то происходит private-наследование.

Можно говорить о том, что public-наследование — это наследование интерфейса, а private-наследование — это наследование реализации (т.е. все элементы наследуются, но становятся закрытыми от доступа из вне).

Статические члены класса

Члены класса, объявленные с модификатором доступа static, называются статическими членами класса. Статические поля и методы доступны без создания объекта данного класса.

Доступ к статическому элементу осуществляется с использованием оператора принадлежности :: , а не через имя экземпляра класса с точкой.

Статические методы могут вызывать и использовать только другие статические методы и статические переменные. Из статического метода нельзя выполнять вызов не статического метода класса.

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

Часто статические переменные называют переменными класса, а «не статические» переменные — переменными экземпляра. Для статических переменных могут использоваться указатели.

Указатель this

Указатель this — это константный указатель на текущий объект (т. е. на объект, к которому применяется вызываемый метод). Этот указатель существует всюду внутри класса, его не надо как-то явно объявлять, к нему можно обращаться внутри любого метода класса.

Предположим, что в классе у нас есть поле с именем f и есть метод, который к этому свойству должен обращаться, но в котором имеется локальная переменная с тем же именем f. Указатель this поможет одновременно использовать поле и локальную переменную: через указатель поле будет доступно как this->f.

Пример:

classExample {private:float f; // Какое-то поле классаpublic: void func(float f) {this->f = f; }};

Данные у каждого объекта свои, а методы класса общие для всех объектов. Указатель this помогает, определить с данными какого объекта будет работать метод.

Разыменовав указатель this можно получить ссылку на объект.

Перегрузка операторов

В С++ можно создавать методы со специальными именами вида: operator *, где * — это один из существующих операторов языка (например, +, -, /, *, = и т.д.).

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

Вызывать этот метод можно обращаясь к нему по указанному символу (в данном случае, *). При этом аргументом метода будет считаться объект стоящий справа от символа, а вызываться метод будет для объекта, стоящего слева от символа.

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

Перегрузка операторов, как и перегрузка функций в целом, реализует принцип полиморфизма.

Пример:

Complex opertor + (Complex a) { Complex tmp;tmp.real = real + a.real;;tmp.img = img + a.img;}

Примериспользования:

Complex a(2,3);Complex b(3,2);Complex c;с = a + b; // Использование перегруженного оператора + для класса Complexcout&lt< c; // 5 + 5i ООП ОТ МИРА DELPHIПрИМЕРЫ

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










Последнее изменение этой страницы: 2018-06-01; просмотров: 398.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...