Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.95
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
#1

Понятия инкапсуляции, полиморфизма и наследования - C++

31.01.2014, 21:46. Просмотров 7070. Ответов 42
Метки нет (Все метки)

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

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

Наследование - возможность объекта иметь потомков, которые имеют расширенный интерфейс.
Пример: Класс - домашний телефон, класс наследник - мобильный телефон с функцией позвонить, и отправить СМС.

Полиморфизм - присваивание действию одного имени разным объектам в иерархии, чтобы потом каждый объект пользовался этим действием, так как угодно именно ему.
Пример из жизни: Расход бензина у различных автомобилей будет рассчитываться по разному в зависимости от количества электроники, которой напичкана машина. (полиморфизм методов).
Телефон стационарный кнопочный, телефон мобильный сенсорный, поля циферблат будут иметь разные типы в первом случае - МатрицаКнопок, во втором случае - СенсорнаяКлавиатура. (Полиморфизм полей класса)

Пример из программирования: перегрузка функций (методов класса наследника), одни и те же поля класса наследника могут иметь различный тип.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.01.2014, 21:46
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Понятия инкапсуляции, полиморфизма и наследования (C++):

Задания о наследовании, инкапсуляции и полиморфизма на C#/ нужно как можно быстро - C++
Создать класс библиографических описаний книг CBookCard. В классе должны быть закрытые поля: автор, заглавие, издательство, год издания,...

Принципы наследования и полиморфизма - C++
Даны натуральное число n, действительные числа a1 a2,...,an. Если последовательность a1 ,a2 ,...,an упорядочена по неубыванию, то...

Чем отличаются структуры для наследования интерфейса от структур для наследования реализаций? - C++
Дорогие программисты, во первых, хочу поздравить вас с Наступающим новым Годом! Я к вам обращаюсь с маленькой просьбой. Я никак не могу...

Обход инкапсуляции класса - C++
#include <iostream> using namespace std; class My_class { private: char* name; public: My_class() {

Об инкапсуляции данных в ООП - C++
Добрый день, почти сделал лабу, но нужно устранить замечание. Идея такая, Должен быть класс поставщик, от него делается два подкласса,...

Нарушение инкапсуляции или нет? - C++
В общем экспериментируя с крестами сделал такую штуку и не могу понять это нарушение инкапсуляции или нет? #include <iostream> class...

42
Avazart
Эксперт С++
7574 / 5559 / 327
Регистрация: 10.12.2010
Сообщений: 24,935
Записей в блоге: 17
01.02.2014, 17:38 #16

Не по теме:

Цитата Сообщение от rrrFer Посмотреть сообщение
Дак вот квадрат является прямоугольником, стороны которого имеют равную длину. Мне кажется, Саттер одобрил бы наследование. (см. правило 37 у Саттера).



Нашел: Мейерс С. -"Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ(2006)"
Правило 32. стр 157,158

Но теперь перед нами встает проблема. Как примирить следующие утверждения?
□ Перед вызовом makeBigger высота s равна ширине.
□ Внутри makeBigger ширина s изменяется, а высота - нет.
□ После возврата из makeBigger высота s снова равна ширине (отметим, что s передается по ссылке, поэтому makeBigger модифицирует именно s, а не его копию).

Так что же?

Добро пожаловать в удивительный мир открытого наследования, где интуиция, приобретенная вами в других областях знания, включая математику, иногда оказывается плохим помощником. Основная трудность в данном случае заключается в том, что некоторые утверждения, справедливые для прямоугольника (его ширина может быть изменена независимо от высоты), не выполняются для квадрата (его ширина и высота должны быть одинаковы). Но открытое наследование предполагает, что все, что применимо к объектам базового класса, - все! -также применимо и к объектам производных классов. В ситуации с прямоугольниками и квадратами (а также в аналогичных случаях, включая множества и списки из правила 38), утверждение этого условия не выполняется, поэтому использование открытого наследования для моделирования здесь некорректно.


Добавлено через 3 минуты
Цитата Сообщение от korvin_ Посмотреть сообщение
С какого объекта реальной жизни взялись названия паттернов «Абстрактная фабрика», «Итератор»?
А что с фабрикой не то ? Фабрика производит продукцию разных типов, чем не соответствие ?
0
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16711 / 6633 / 433
Регистрация: 12.06.2012
Сообщений: 19,880
Завершенные тесты: 1
01.02.2014, 17:52 #17
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
никаких реализаций не сокрыто
Т.е., вы всегда знаете, из чего состоят все вещества вокруг, машина у вас - полностью прозрачная (также, как и квартира) - ведь ничего же не скрыто?
Я не спорю, не всегда легко найти аналогию - но это не всегда значит, что ее нет.
0
rrrFer
Заблокирован
01.02.2014, 18:34 #18
Цитата Сообщение от Avazart Посмотреть сообщение
Может у Мейерса ? У него вроде есть об этом и у него "правила", а у Саттера вроде в "задачах" все.
Может и у Мейерса, но я Саттера читал.
Открытое наследование в соответствии с принципом подстановки Лисков (Liskov Substitution Principle [Liskov88]) всегда должно моделировать отношение "является" ("работает как"): все контракты базового класса должны быть выполнены, для чего все перекрытия виртуальных функций-членов не должны требовать большего или обещать меньше, чем их базовые версии. Код, использующий указатель или ссылку на Base, должен корректно вести себя в случае, когда указатель или ссылка указывают на объект Derived.
Цитата Сообщение от korvin_ Посмотреть сообщение
http://citforum.ru/programming/digest/lspv/
Спасибо за ссылку, там как раз пример с квадратом и прямоугольником. Весь текст я не осилил, но понял, что автор пытается доказать, что именно в случае наследования квадрата от прямоугольника правило подстановки нарушается. Посмотрел его аргументы (без контекста) - не убедился. Да и сам автор пишет:
Можно было бы возразить автору, что принцип подстановки плохо сформулирован, что не определен термин замена (хотя в данном примере все понятно: в программу передается ссылка на объект подкласса), что непонятен термин поведение программы и так далее.
Суть в том, что пример взят простой. С точкой и окружностью сложнее. Для этих случаев все разобрано по полочкам, но даже так нет единого мнения и холивары продолжаются.

Цитата Сообщение от Avazart Посмотреть сообщение
Основная трудность в данном случае заключается в том, что некоторые утверждения, справедливые для прямоугольника (его ширина может быть изменена независимо от высоты), не выполняются для квадрата (его ширина и высота должны быть одинаковы).
Но открытое наследование предполагает, что все, что применимо к объектам базового класса, - все! -также применимо и к объектам производных классов. В ситуации с прямоугольниками и квадратами (а также в аналогичных случаях, включая множества и списки из правила 38), утверждение этого условия не выполняется, поэтому использование открытого наследования для моделирования здесь некорректно
Если прочитать все внимательно, а не только выделенный вывод в конце - то можно заменить, что все не так гладко.
Это очень коротко изложенное содержание статьи по ссылке korvin_-а .
Источник холиваров в том, что математика вообще не определяет никаких операций над прямоугольником. Автор этого текста почему-то решил, что надо изменять его высоту, независимо от ширины. У меня есть сомнения. Мало того, квадрат может предоставлять такой же интерфейс, а ("контракт" у Саттера) значит, принцип подстановки сработает. Но в реализации методов будет фича - при изменении ширины будет изменяться высота. Почему-то в этом случае такая фича всех пугает, но в более сложных примерах, возникающих в практике постоянно - нет.
0
ValeryS
Модератор
6967 / 5304 / 522
Регистрация: 14.02.2011
Сообщений: 17,885
01.02.2014, 18:50 #19
Цитата Сообщение от rrrFer Посмотреть сообщение
Математически - окружность - множество точек, равноудаленных от заданной.
а давай по другому
точка есть окружность с нулевым радиусом

Цитата Сообщение от gray_fox Посмотреть сообщение
Мы же не наследуем класс квадрата от класса прямоугольника, правда?
а почему бы и нет
квадрат частный случай прямоугольника
прямоугольник частный случай параллелограмма
параллелограмм частный случай четырехугольника

это я к тому что проектирования наследования не так просто как кажется на первый взгляд
0
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
01.02.2014, 19:03  [ТС] #20
Цитата Сообщение от ValeryS Посмотреть сообщение

а почему бы и нет
квадрат частный случай прямоугольника
прямоугольник частный случай параллелограмма
параллелограмм частный случай четырехугольника

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

тогда получается, что проще всего базовым классом взять надо квадрат, потому что у него всего 1 угол и одна сторона и от него уже отнаследовать четырёхугольник, добавив ещё 3 поля для длин сторон и 3 поля для углов
0
ValeryS
Модератор
6967 / 5304 / 522
Регистрация: 14.02.2011
Сообщений: 17,885
01.02.2014, 19:17 #21
Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
а разве наследование не предполагает, расширение интерфейса базового класса?
я не знаю как там по научному, для меня нет
наоборот у наследника может идти упрощение
в смысле внутри может и побольше будет
а снаружи нет
например
C++
1
2
3
4
5
6
class square : public rectangle
{
public square(int a);
}
square :square (int a) :rectangle(a,a)
{};
все остальное от прямоугольника
какие свойства есть у квадрата которых нет у прямоугольника?
а вот если наоборот
то придется переписывать расчет площади, периметра
вводить еще одну сторону, причем не понятно что считать шириной а что высотой
0
Avazart
Эксперт С++
7574 / 5559 / 327
Регистрация: 10.12.2010
Сообщений: 24,935
Записей в блоге: 17
01.02.2014, 19:44 #22
Цитата Сообщение от rrrFer Посмотреть сообщение
Если прочитать все внимательно, а не только выделенный вывод в конце - то можно заменить, что все не так гладко.
Это очень коротко изложенное содержание статьи по ссылке korvin_-а
Это не изложение статьи, это короткая цитата из книги Мейерса
Лично мне больше понравился пример "птица/пингвин", описанный до разбора примера "прямоугольник/квадрат"

А выделенный текст касался слов:
Цитата Сообщение от rrrFer
Мне кажется, Саттер одобрил бы наследование

Цитата Сообщение от rrrFer Посмотреть сообщение
Может и у Мейерса, но я Саттера читал.
Странно чет у Саттера не помню такого, может книга другая, можете указать на место в книге ?


Цитата Сообщение от ValeryS Посмотреть сообщение
точка есть окружность с нулевым радиусом
Не это не правильно, по крайней мере с математической точки зрения.
Точка в математике не может иметь радиус, и странно будет если радиус появится в интерфейсе класса точки.

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


Добавлено через 5 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
это я к тому что проектирования наследования не так просто как кажется на первый взгляд
Выясни нужный интерфейс, выдели общие черты моделируемых объектов, и сложности отпадут сами.
0
ValeryS
Модератор
6967 / 5304 / 522
Регистрация: 14.02.2011
Сообщений: 17,885
01.02.2014, 19:50 #23
Цитата Сообщение от Avazart Посмотреть сообщение
Точка в математике не может иметь радиус.
ну а нулевой радиус это не отсутствие радиуса?

а в программировании точку лучше вообще вынести за иерархию, по моему, никакой функциональности она не несет, а проблем добавит
например еще можно от точки наследовать круг(окружность) добавив радиус и весь функционал
где точка будет центром
а как наследовать эллипс у которого два центра?

Добавлено через 1 минуту
Цитата Сообщение от Avazart Посмотреть сообщение
Выясни нужный интерфейс, выдели общие черты моделируемых объектов,
это ты мне объясняешь?
у меня то сложностей как раз нет
а у начинающих есть именно в выяснении интерфейса и общих черт
0
Avazart
Эксперт С++
7574 / 5559 / 327
Регистрация: 10.12.2010
Сообщений: 24,935
Записей в блоге: 17
01.02.2014, 20:02 #24
Цитата Сообщение от ValeryS Посмотреть сообщение
ну а нулевой радиус это не отсутствие радиуса?
Да и что на это скажет пользователь кода ?

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

Цитата Сообщение от ValeryS Посмотреть сообщение
а как наследовать эллипс у которого два центра?
А нефиг лепить все в кучу.
Единственно что тут можно сделать выделить общего предка с общим интерфейсом.
0
ValeryS
Модератор
6967 / 5304 / 522
Регистрация: 14.02.2011
Сообщений: 17,885
01.02.2014, 20:05 #25
Цитата Сообщение от Avazart Посмотреть сообщение
Да и что на это скажет пользователь кода ?
в смысле???
C++
1
2
3
4
5
6
7
class Point : public Circle
{
public:
 Point( int x,int y):
...................................
 
Point::Point(int x, int y) : Circle(x,y,0)
Но это так к слову
я же говорил я бы вывел точку из иерархии
нет у неё свойств

Добавлено через 1 минуту
Цитата Сообщение от Avazart Посмотреть сообщение
А нефиг лепить все в кучу.
Единственно что тут можно сделать выделить общего предка с общим интерфейсом.
ну я и говорю
эллипс- окружность- точка
более логично чем наоборот
0
Dmitriy_M
1400 / 1283 / 119
Регистрация: 20.03.2009
Сообщений: 4,575
Записей в блоге: 11
01.02.2014, 20:10 #26
Цитата Сообщение от Avazart Посмотреть сообщение
зачем ?
Через пол года-год, ты уже не вспомнишь как работает твоя программа.
Цитата Сообщение от Avazart Посмотреть сообщение
Другое дело что не всегда можно провести эту аналогию, без ущерба в реализации.
Никакая аналогия не поможет, когда хреново проименованы классы и функции.

Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
а разве наследование не предполагает, расширение интерфейса базового класса?
Нет.

Цитата Сообщение от el_gato_de_Ch Посмотреть сообщение
тогда получается, что проще всего базовым классом взять надо квадрат, потому что у него всего 1 угол и одна сторона и от него уже отнаследовать четырёхугольник, добавив ещё 3 поля для длин сторон и 3 поля для углов
Нельзя. Наследник так же будет квадратом, а значит нельзя менять соотношение сторон.
0
Avazart
Эксперт С++
7574 / 5559 / 327
Регистрация: 10.12.2010
Сообщений: 24,935
Записей в блоге: 17
01.02.2014, 20:22 #27
Цитата Сообщение от ValeryS Посмотреть сообщение
в смысле???
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class Circle
{
  public:
    // ...
     int getRadius()const;
     void setRadius(int R);
}
 
class Point : public Circle
{
public:
  /*  Нафига пользователю акцессоры радиуса ? */
}
Правильнее:
C++
1
2
3
4
5
6
7
8
9
10
class Circle
{
  public:
     // ...
     int getRadius()const;
     void setRadius(int R);
  private:
     Point center_;
     int r_;
}
Цитата Сообщение от ValeryS Посмотреть сообщение
ну я и говорю
эллипс- окружность- точка
более логично чем наоборот
Нет, создать абстрактный класс, от него наследовать перечисленные ...
В зависимости от конечной цели определить виртуальные методы, например drow(), getCenter(), moveTo().
0
ValeryS
Модератор
6967 / 5304 / 522
Регистрация: 14.02.2011
Сообщений: 17,885
01.02.2014, 20:25 #28
Цитата Сообщение от Avazart Посмотреть сообщение
Правильнее:
Цитата Сообщение от Avazart Посмотреть сообщение
Point center_;
ну а я про что?
Цитата Сообщение от ValeryS Посмотреть сообщение
я бы вывел точку из иерархии
ну никаким боком она к кругу(окружности)
используется? да
является наследником/родителем? нет
но ежли кому вздумается встроить её в иерархию то лучше уж из круга, чем наоборот

встречались мне на просторах интернета лекции,в которых утверждалось что точка базовый класс и из него растут все фигуры
0
Kuzia domovenok
2128 / 1956 / 195
Регистрация: 25.03.2012
Сообщений: 6,808
Записей в блоге: 1
01.02.2014, 20:28 #29
rrrFer, вот именно! Когда мы применяем ООП мы в первую очередь следуем определённому набору принципов, как напр. ты сказал: "всё, что применимо к базовому должно быть применимо к производному" и многие другие. То есть принципы всё же стоят впереди, а аналогии с реальностью вы подгоняете под них.
Однако найти такие аналоги можно для любой парадигме, особенно если она близка тебе как программисту, часто тобой применяется.
Но, говоря о том, что к ООП не применима аналнгия с жизнью, я хотел прежде всего обратить на это внимание ТС и всех начинающих программистов. Ведь как будет мыслить человек, которому ничего об ООП не рассказали кроме определения из словаря? Которому сказали: "задавай как в жизни!" ?
Он начнёт задавать объекты именно в сответствие с тем, что ему самому взбрело вложить в это понятие: будет наследовать круг от точки, квадрат от прямоугольника...
В отдельных случаях (и я встречал такие в вопросах на форуме) новички понимают объекты в самом буквальном смысле: "это когда открыл редактор форм и мышкой понаставил ОБЪЕКТОВ!", т.е. ООП для человека, не задумывающегося об этих ваших абстракциях звучит как "моделирование"! Само собой, если б это было так, ни о каком полиморфизме и речи б не шло. Наоборот, мы бы сотни объектов в погоне за "моделью мира".

Отсюда вывод: не надо путать причину со следствием. Можно решать в первую очередь проблемы своего приложения: выделять в нём подсистемы, обобщать для них интерфейсы... И пусть при этом очень возможно какие-то классы у вас и будут позаимствованы из реальности... Но это не значит, что ООП это "моделирование". Если б это было так, ни о каком полиморфизме и речи бы не было! Наоборот, мы бы создавали сотни объектов в погоне за "моделью мира"!
0
Avazart
Эксперт С++
7574 / 5559 / 327
Регистрация: 10.12.2010
Сообщений: 24,935
Записей в блоге: 17
01.02.2014, 20:30 #30
Цитата Сообщение от ValeryS Посмотреть сообщение
ну никаким боком она к кругу(окружности)
используется? да
Отношение "реализуется посредством" (хотя конечно для таких простых классов звучит преувеличено)
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.02.2014, 20:30
Привет! Вот еще темы с ответами:

Нарушение инкапсуляции или нет? - C++
Есть такой код: class Tune { private: vector<int> A; public: const vector<int>& get_A() const { return A; } // <- не...

Провете класс на предмет ошибок инкапсуляции - C++
Добрый день! Недавно начал изучение ООП C++ и вот настал момент, когда я создал свой первый класс и обьект. Хочу попросить проверить его на...

Виды полиморфизма C++ - C++
Разбираю полиморфизм. Наткнулся на классификацию с тремя видами:1.специальный, 2.параметрический и 3.подтипов(включения). Все ли...

иллюстрация полиморфизма - C++
Доброго времени суток!написал примитив для иллюстрации полиморфизма,ориентировался по видеокурсам с ТыТрубы #include<iostream.h> ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru