Перейти к содержимому

Фотография

Кто и где лучший программист?Кто они лучшие и как их определить?


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 220

#101
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений

энтирэсно... [url=http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.6]
<...>
мне показалсь, или вы, Visual1, хотели доказать, что Rectangle:Square лучше, чем Square:Rectangle?

Вам показалось. Он не "лучше" и не "хуже", он другой, не производный. Приведенная вами ссылка говорит о том же.
  • 0

#102
yedyge

yedyge
  • Свой человек
  • 879 сообщений
тогда объясните от чистого сердца простыми словами, что значит:
"все контракты базового класса должны быть выполнены, для чего все перекрытия виртуальных функций-членов не должны требовать большего или обещать меньше, чем их базовые версии."

чего Square::SetWidth() требует большего или обещает меньшее в случае Square:Rectangle ?
  • 0

#103
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений

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

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

Bad inheritances always have a base class with an extra capability (often an extra member function or two; sometimes an extra promise made by one or a combination of member functions) that a derived class can't satisfy. You've either got to make the base class weaker, make the derived class stronger, or eliminate the proposed inheritance relationship.

Лучше и не скажешь.

чего Square::SetWidth() требует большего или обещает меньшее в случае Square:Rectangle ?

Square требует большего, чем Rectangle - он требует одновременно изменять высоту и ширину. Или можно сказать, что он обещает меньше, чем обещает Rectangle - он не обещает изменять высоту и ширину независимо друг от друга.
  • 0

#104
yedyge

yedyge
  • Свой человек
  • 879 сообщений
мне не понятно, что такое "усилить наследника".
потому, что смысла два и они противоположны:
1.усилить - расширить его функциональность над базовым.
2.усилить - сделать более строгими (сильными) ограничения наследника по сравнению с базовым.
_____________________________________

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

так что можно ещё раз медленно объяснить?
  • 0

#105
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений
ОК, давайте медленно. Мне и самому интересно. Чтобы в этом разобраться, обратимся к статье "The Liskov Substitution Principle". Вообще-то можно, не вникая в тонкости, просто ограничиться требованием "all derivatives must conform to the behavior that clients expect of the base classes that they use" - все производные классы должны соответствовать поведению, которое клиенты ожидают от базовых классов, которые они (т.е. клиенты) используют.

Но автор статьи идет дальше - он использует концепцию "дизайн, обусловленный контрактом" (design by contract), которую он привлекает из давней работы Бертрана Майера (Object Oriented Software Construction, Bertrand Meyer, Prentice Hall, 1988). Согласно ей, методы классов, помимо прямой и явной своей работы, также неявно декларируют предварительные условия (предусловия) и окончательные условия (постусловия). Чтобы метод мог выполняться, предусловия должны быть истинными. После завершения своей работы метод должен гарантировать, что постусловие будет истинным. Например, в случае метода Rectangle::SetWidth(double w) постусловие будет таким:
assert((itsWidth == w) && (itsHeight == old.itsHeight));  // ширина стала равной заданной, а высота должна остаться прежней.
Правило для предусловий и постусловий, которому должны следовать производные классы, сформулировано Майером так (перевод мой):

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

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

Очевидно, что постусловие Square::SetWidth(double w) более слабое, чем постусловие Rectangle::SetWidth(double w), так как оно не поддерживает утверждение базового класса "(itsHeight == old.itsHeight)". Следовательно, Square::SetWidth(double w) нарушает контракт базового класса.

Статья отличная, из нее можно узнать очень интересные вещи. Оказывается, существуют языки программирования, например, Eiffel, которые непосредственно, в самом языке, поддерживают предусловия и постусловия! Программист может напрямую декларировать их, и заставлять runtime-систему выполнять проверку их соблюдения. В С++ это невозможно - разве что записывать эти условия для каждого метода в виде комментариев и вручную проверять их.
  • 0

#106
yedyge

yedyge
  • Свой человек
  • 879 сообщений
спасибо.

>Очевидно, что постусловие Square::SetWidth(double w)<...>
имхо не очевидно.

постусловие имеет два пункта:
1.(new.width == param) == true
2.(new.height == old.height) == true

что равнозначно с:
1.(new.width == param) == true
2.(new.height != old.height) == false

усиление условия это ведь повышение количества true?
усиляем:
1.(new.width == param) == true
2.(new.height != old.height) == true

таким образом постусловие Square::SetWidth() более сильное, чем Rectangle::SetWidth().
  • 0

#107
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений

спасибо.

>Очевидно, что постусловие Square::SetWidth(double w)<...>
имхо не очевидно.

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

Clearly, the postcondition of Square::SetWidth(double w) is weaker than the postcondition of Rectangle::SetWidth(double w) above, since it does not conform to the base class clause "(itsHeight == old.itsHeight)". Thus, Square::SetWidth(double w) violates the contract of the base class.


  • 0

#108
yedyge

yedyge
  • Свой человек
  • 879 сообщений
то есть вы согласны, что трактовка строгости/мягкости легко оборачивается на противоположную.
и что делать станем?
  • 0

#109
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений
Нет, в трактовке строгости/мягкости я полностью согласен с автором.

> усиление условия это ведь повышение количества true?

Я так не думаю. Суммарное увеличение количества условий true и false, которые должны выполняться наследником, может и возрастать, но при этом как минимум должны выполняться все постусловия родителя. Остальное (в сторону дальнейшего усиления постусловий родителя в наследнике) - опционально. Мысль автора такова: если наследник не выдерживает хотя бы одно из постусловий родителя - значит, постусловия наследника более слабые. Квадрат не выдерживает постусловие обеспечения независимости высоты при задании ширины, которое обеспечивает прямоугольник. Значит, квадрат удовлетворяет меньшему количеству постусловий, чем прямоугольник - хотя и вводит свое, характерное только для него, постусловие равенства сторон, которое выполняется (true). Следовательно, у квадрата постусловия более слабые, несмотря на сохранение или увеличение общего числа проверок, и наследником прямоугольника он быть не может.

Сообщение отредактировал Visual1: 02.09.2006, 00:15:03

  • 0

#110
yedyge

yedyge
  • Свой человек
  • 879 сообщений
заморочено. и главная обида - с понталыку сбил.
надо было мне сразу не вестись на условия задачи, а сделать по-своему.
class Rectangle
{
double x, y;
public void setx(double);
public void setx(double);
public void setsquare(double, double);
public double getx();
public double gety();
public bool issquare();
};
  • 0

#111
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений
Обидчивый какой. :smoke: Никто тут никого не заморачивал и "с панталыку" не сбивал. Я изложил все подробности насколько возможно добросовестно и ясно. Вы мне даже "спасибо" сказали. :smoke:

Разговор был о наследовании, так где же в последнем предложенном Вами варианте класс, производный от Rectangle?

Как ввод двух дополнительных открытых функций (setsquare и issquare) в класс Rectangle относится к наследованию квадрата из прямоугольника?
  • 0

#112
yedyge

yedyge
  • Свой человек
  • 879 сообщений
вот это и есть заморачивание честных наивных граждан.
в данном случае при такой муторности наследования - оно, то есть наследование, не уместно.
для получения квадрата из прямоугольника наследования не нужно. ибо "квадрат есть в некотором разе прямоугольник".

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

Сообщение отредактировал yedyge: 05.09.2006, 21:39:25

  • 0

#113
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений

вот это и есть заморачивание честных наивных граждан.

1. Эти слова насчет "заморачивания" уж не в мой ли адрес произносятся? Ну-ка объяснитесь, как это понимать.

2. Также насчет "честных и наивных граждан": отучайтесь говорить за всех.

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

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

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

Вы что здесь, изложение пишете? Своими словами о том, о чем вам недавно здесь же рассказали?

Сообщение отредактировал Visual1: 05.09.2006, 22:25:44

  • 0

#114
yedyge

yedyge
  • Свой человек
  • 879 сообщений
аха, вы настаиваете на наследовании, а участники темы заморочились :smoke:
затем, заморочив, вы доказываете, что пошутили над народом :smoke:
вот о том и тема.
  • 0

#115
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений

аха, вы настаиваете на наследовании, а участники темы заморочились :smoke:

1. Глупая шутка (если это шутка). Я настаиваю как раз наоборот, на невозможности наследования в данном случае. Причем уже много дней подряд. Перечитайте предыдущие страницы. И прекратите искажать факты, иначе наш дальнейший разговор будет невозможен.
2. Перестаньте говорить от имени "участников темы", которые якобы "заморочились". Если лично вы заморочились, то это еще не все "участники темы". Я никого не заставляю обсуждать, и никому не навязываюсь. Если можете предложить что-нибудь более интересное, буду рад увидеть.

затем, заморочив, вы доказываете, что пошутили над народом :smoke:
вот о том и тема.

Смайлик здесь неуместен, в качестве шутки такие заявления не проходят. Где я "доказываю", что я "пошутил над народом"? Факты? Цитаты? Ссылки? И опять вы про "народ". С вами все в порядке?

Сообщение отредактировал Visual1: 06.09.2006, 19:14:18

  • 0

#116
ceasar

ceasar
  • Частый гость
  • 65 сообщений

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


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

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

Еще раз прошу не ругать особо не разбирался в чем вопрос. Читал тока пост который указан выше в теге
  • 0

#117
Visual1

Visual1
  • В доску свой
  • 1 198 сообщений
Приятно, что есть еще интересующиеся этим вопросом. Хотя жаль, что Вы "особо не читали", поскольку "сильно устали". :smoke: По сути: да, приведенная цитата - мои слова, и я от них не отказываюсь. Однако заметьте, что даже здесь, когда мне самому еще было многое не понятно, все-таки уже подчеркнута необходимость принятия специальных мер, чтобы производный класс мог вести себя как базовый. Эти "специальные меры" так и не были найдены, а когда я разобрался в статье "The Liskov Substitution Principle", стало понятно, что наследование квадрата от прямоугольника невозможно.

И насчет Вашего предложения создать абстрактный класс. Это можно, но придем к тому же: прямоугольник и квадрат (а заодно треугольник, овал, круг и другие плоские фигуры) будут производными от абстрактного класса "Фигура", но опять же - квадрат не будет потомком прямоугольника. Разве не так?
  • 0

#118
ceasar

ceasar
  • Частый гость
  • 65 сообщений
точно не могу сказать завтра попробую реализовать это посмотрю что выйдет с этого
  • 0

#119
hes

hes
  • В доску свой
  • 1 567 сообщений
а - Объект б -Свойства в - Методы

1 абстрактный класс
а геом. фигура в - абстрактный метод вычисления площади фигуры

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

3 Производный от объекта 1, либо от объекта 2, кому как нравится
прямоугольник
примечание: в принципе это лишь частный случай n-угольника, можно на нем и не заморачиваться

4 Производный от объекта 1
а - Овал (круг как известно тоже овал), но отношение радиусов кривизны в нем = 1 б - Радиус 1, Радиус 2, Отношение радиусов в - перегруженный метод вычисления площади фигуры, функция, определяющая, круг ли это, по отношению радиусов

5 Производный от объекта 4
а - Сектор б - Угол в - перегруженный метод вычисления площади фигуры

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

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

#120
Pooh

Pooh
  • В доску свой
  • 1 898 сообщений
http://sztywny.titan...ammers-answers/
  • 0


Количество пользователей, читающих эту тему: 1

пользователей: 0, неизвестных прохожих: 1, скрытых пользователей: 0

Размещение рекламы на сайте     Предложения о сотрудничестве     Служба поддержки пользователей

© 2011-2022 vse.kz. При любом использовании материалов Форума ссылка на vse.kz обязательна.