powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Наследование(ООП). растолкуйте
25 сообщений из 120, страница 3 из 5
Наследование(ООП). растолкуйте
    #35959677
tchingizя тоже пример с квадратами- прямоугольниками рассматриваю уже год это и не понимаю.
Я все больше склоняюсь к мысли, что заменять T на S и требовать неизменности поведения любой программы бессмысленно. Что делать с программой, которая вообще объекты не использует, а тупо выводит на экран название используемого класса (типа)? Ее поведение изменится в любом случае, так что можно придти к выводу, что в природе не существует "подтипов" вообще... Это неконструктивно))

tchingizдавай так.
деление явно должно быть перегружено
берем программу
Код: plaintext
1.
2.
3.
int P ( float x) 
{
return x/ 2 
}
при подстановке o1, целой единицы вызовется целое деление - результат будет 0.
при подстановке плавающей единицы результат будет 0.5
результат будет всегда 0, ведь возвращаемый тип - int.
думаю, вы имели ввиду что-то вроде этого:
Код: plaintext
1.
template<T>
T half(T x) { return x /  2 ; } 
Тогда действительно получается, что замена x с float на int меняет поведение функции для нечетных х. Но мне по-прежнему не очевидно, что этот пример олицетворяет принцип Лисков, поскольку, опять же, в нем нет ни слова про замену классов, только про замену объектов.
Вот возьмем функцию
Код: plaintext
float half(float x) { return x/ 2 ; }
и сделаем всё четко по принципу: T - float, S - int; для любого int'а есть соответствующий float, такой, что если в любой программе использующей эту функцию заменить его на соответстущий int, то поведение программы не изменится; что ж, для с/с++, насколько мне известно, это действительно так, так что int is subtype of float...
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959681
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а почему результат обработки наследника должен совпадать с результатом обработки родителя?
Пример: есть класс форма. От его наследуеться класс форма с кнопкой. Медод вывода на экран даст разные результаты. А что, форма с кнопкой не являеться формой?
а про деление нацело - дак это и неправильно. потомучто в природе в общем случае даже деление целых чисел дает действительный результат резльтат, или, при делении на ноль, результат не число.
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959690
ZyK_BotaNа почему результат обработки наследника должен совпадать с результатом обработки родителя?
Никто не говорит, что должно. Требование, как я его понимаю, совершенно иное: чтобы для всех возможных экземпляров класса-наследника существовал хотя бы один экземпляр класса-родителя такой, что результат его обработки в любой программе аналогичен.

ZyK_BotaNПример: есть класс форма. От его наследуеться класс форма с кнопкой. Медод вывода на экран даст разные результаты. А что, форма с кнопкой не являеться формой?
Всё здесь в порядке: в классе "форма", разумеется, есть объекты, поведение которых полностью идентично поведению некоторому объекту класса "формы с кнопкой"; по-моему, это очевидно?

ZyK_BotaNа про деление нацело - дак это и неправильно. потомучто в природе в общем случае даже деление целых чисел дает действительный результат резльтат, или, при делении на ноль, результат не число.
Так о том и спич - надо ли требовать, чтобы результат деления был того же типа что и аргументы или нет? Возьмите два рациональных числа, второе из которых не ноль; поделите первое на второе, обязательно получите рациональное число. А вот целые числа таким свойством не обладают. Вот и вопрос: значит ли это, что целые числа не являются подклассом рациональных (как не обладающие свойством, которым обладают рациональные числа) или все-таки является.

Вот еще один довод в пользу того, чтобы не считать обязательным сохранение всех свойств типа (а не объектов типа ): возьмем некоторые тип T и подтип S, пусть существует объект о1, принадлежащий Т и не принадлежащий S, но тогда T обладает тем свойством, что содержит обхект о1, а S таким свойством не обладает, значит S не являеттся подтипом Т, полученное противоречие означает что объекта о1 не существует, или, иными словами, любой подтип совпадает со своим надтипом. Это, опять же, неконструктивно)))
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959692
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton 2 Все

Еще раз напоминаю, что без привязки к предметной области, наша дискуссия будет просто философствованием. Будет-ли квадрат наследником прямоугольника или нет - это определит сама прирада задачи. Быть может в какой-нибудь геометрии Лобачевского-Римана или Егорыча-Чингиза существует "точка" с "ненулевой массой" или квадрат с отрицательной площадью. Всё будет иметь своё место и смысл!! Но..... как только мы ОПРЕДЕЛИМСЯ с этой природой.при привязке к предметной области вопрос переходит в практическую плоскость и сразу становится оффтопиком,
потому как тред начался со слов "философский ступор" ну и потеряет свою остроту и интересность.
Ну а если серьёзно, то я в выделенной цитате не вижу разногласий с моей позицией. Только от задачи зависит, может-ли квадрат наследоваться от прямоугольника, ромба, параллелограмма, круга или точки, или не может.
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959703
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
l s p не понимаю
Так о том и спич - надо ли требовать, чтобы результат деления был того же типа что и аргументы или нет? Возьмите два рациональных числа, второе из которых не ноль; поделите первое на второе, обязательно получите рациональное число. А вот целые числа таким свойством не обладают. Вот и вопрос: значит ли это, что целые числа не являются подклассом рациональных (как не обладающие свойством, которым обладают рациональные числа) или все-таки является. на мой взгляд ответ однозначный - целые числа не являются подклассом рациональных для случаев, когда операция деления определена. Потому что я, как клиент класса Float, могу совершенно спокойно написать такой код:
Код: plaintext
1.
2.
Float half( Float var ) { return var/ 2 ; }
Float foo( Float *something) { return  1 /half( something ); }
и буду вполне обоснованно надеятся, что передав в функцию foo указатель на Integer : public Float не получу деления на 0... ха!
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959707
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tchingiz

Код: plaintext
1.
2.
3.
4.
5.
int P ( float x) 
{
return x/ 2 
}


при подстановке o1, целой единицы вызовется целое деление - результат будет 0.
при подстановке плавающей единицы результат будет 0.5
тут ошибочка естественно
Код: plaintext
1.
2.
3.
4.
5.
float P ( float x) 
{
return x/ 2 
}

...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959708
egorychна мой взгляд ответ однозначный - целые числа не являются подклассом рациональных для случаев, когда операция деления определена. Потому что я, как клиент класса Float, могу совершенно спокойно написать такой код:
Код: plaintext
1.
2.
Float half( Float var ) { return var/ 2 ; }
Float foo( Float *something) { return  1 /half( something ); }
и буду вполне обоснованно надеятся, что передав в функцию foo указатель на Integer : public Float не получу деления на 0... ха!
А что это за язык? Вы, что ли, имеете ввиду различные машинные представления int и float?
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959710
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
l s p не понимаю
Код: plaintext
float half(float x) { return x/ 2 ; }
и сделаем всё четко по принципу: T - float, S - int; для любого int'а есть соответствующий float, такой, что если в любой программе использующей эту функцию заменить его на соответстущий int, то поведение программы не изменится; что ж, для с/с++, насколько мне известно, это действительно так, так что int is subtype of float...
не согласен.
в теле программы x заменим на 1.

упростим. параметр не нужен

Код: plaintext
float half() { return  1 . 0 / 2 ; }
и
Код: plaintext
float half() { return  1 / 2 ; }

вернут разные результаты
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959712
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
l s p не понимаюtchingizя тоже пример с квадратами- прямоугольниками рассматриваю уже год это и не понимаю.
Я все больше склоняюсь к мысли, что заменять T на S и требовать неизменности поведения любой программы бессмысленно. Что делать с программой, которая вообще объекты не использует, а тупо выводит на экран название используемого класса (типа)? Ее поведение изменится в любом случае, так что можно придти к выводу, что в природе не существует "подтипов" вообще... Это неконструктивно))
.
это к Лисков, она у нас получатель премии Тьюринга.
Думаю ее принцип есть следствием отсутствия человеческих определений в ооп,
и желанием понять, что же имеется ввиду.
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959714
tchingizне согласен.
в теле программы x заменим на 1.
упростим. параметр не нужен
Код: plaintext
float half() { return  1 . 0 / 2 ; }
и
Код: plaintext
float half() { return  1 / 2 ; }

вернут разные результаты
Так вы не объект заменили, вы программу (функцию) изменили. Вообще, с чего вдруг второй вариант написан "in terms of int", а не "in terms of float"?
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959715
tchingizэто к Лисков, она у нас получатель премии Тьюринга.
Думаю ее принцип есть следствием отсутствия человеческих определений в ооп,
и желанием понять, что же имеется ввиду.
Так я все никак не увижу где бы Лисков требовала заменяемости типа родителя на тип наследника.
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959717
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
псевдокодом написал, имелось ввиду следующее:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class Float {
   ...
};
Float & operator/( const Float & lhs, const Float & rhs ) { ... }

class Integer : public Float {
   ...
};

Float half( Float var ) { ... }
Float foo( Float *something ) { ... }
мы же о наследовании, в общем-то говорим.
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959720
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2
l s p не понимаю
и сделаем всё четко по принципу: T - float, S - int; для любого int'а есть соответствующий float, такой, что если в любой программе использующей эту функцию заменить его на соответстущий int, то поведение программы не изменится; что ж, для с/с++, насколько мне известно, это действительно так, так что int is subtype of float...
имхо, это не то, что имеет ввиду Лисков,
так как в любой программе использующей это функцию, не должно сначала выполняться
преобразование типа int в float, так как тогда, на деле передается объект из T.
Склонен считать, что подстановка объектов должна выполнятся в теле функции P
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959721
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tchingiz,

оператор "/" переопределен для разных типов(int, float) так, что несет разную смысловую нагрузку, поэтому очевидно что при работе с разными типами, получаем разный результат.

а если бы создатели языка действительно наследовали int от float :), то оператор деления нельзя было бы переопределить как деление нацело и в итоге мы бы получали в результате 0.5 даже в случае целого типа

пример с делением не доказал невозможность наследования целых от рациональных
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959722
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorych,

ну и оператор деления для Integer определить с той же семантикой, как у встроенного типа - и всё, привет семье. Неожиданные ошибки времени выполнения в клиентском коде, использующем Integer через указатель на базовый класс ( Float ) обеспечены.
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959725
egorychпсевдокодом написал, имелось ввиду следующее:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class Float {
   ...
};
Float & operator/( const Float & lhs, const Float & rhs ) { ... }

class Integer : public Float {
   ...
};

Float half( Float var ) { ... }
Float foo( Float *something ) { ... }
мы же о наследовании, в общем-то говорим.
Отлично, и что же вас смущает?
Какой бы Integer в какой угодно программе вы бы ни взяли, вы всегда можете подыскать такой Float, что замена этого Integer'а на этот Float даст полностью аналогичное поведение программы. (например, 1 заменить на 1.0, 2 на 2.0 и т.д.). Функция half при этом совершенно не должна переписываться под тип Integer - замене ведь подлежат только объекты; и возвращать она всегда будет Float, что для Integer'ов, что для Float'ов, и для 1 и для 1.0 возвращать будет одно и то же; по мне так, все шито-крыто))
(в терминах квадратов-прямоугольников: поскольку для любого квадрата всегда можно указать прямоугольник, который ведет себя абсолютно так же (обе стороны которого равны стороне квадрата, очевидно), то, согласно Лисков, квадрат является подтипом прямоугольника)
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959727
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZyK_BotaNа если бы создатели языка действительно наследовали int от float :), то оператор деления нельзя было бы переопределить как деление нацело и в итоге мы бы получали в результате 0.5 даже в случае целого типакак это возможно, интересно? Что будет вот здесь:
Код: plaintext
int c = half(  1  ); // чему будет равно значение с? 
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959728
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
l s p начинаю пониматьtchingizэто к Лисков, она у нас получатель премии Тьюринга.
Думаю ее принцип есть следствием отсутствия человеческих определений в ооп,
и желанием понять, что же имеется ввиду.
Так я все никак не увижу где бы Лисков требовала заменяемости типа родителя на тип наследника.
тут недопонял
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959729
egorychegorych,

ну и оператор деления для Integer определить с той же семантикой, как у встроенного типа - и всё, привет семье. Неожиданные ошибки времени выполнения в клиентском коде, использующем Integer через указатель на базовый класс ( Float ) обеспечены.
А, переопределением операторов заняться хотите )) это неприлично, и приводит к неразрешимости вопроса о подтипе по Лисков:
If type T denotes a set of values that carry their own behavior, and if values of type S can override some of T values behavior, the LSP is undecidable. Indeed, a mechanical application of LSP must at least be able to verify that all methods overridden in S terminate whenever the corresponding methods in T terminate. This is generally impossible.

К чему переопределять-то? Что, операция деления двух целых чисел не такая, как для деления двух рациональных? Чему противоречит то, что результат будет нецелым? Вы же сами себя в рамки замкнутости относительно деления и загоняете, а потом говорите что раз эти рамки есть то наследование невозможно))
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959732
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
l s p начинаю понимать
(в терминах квадратов-прямоугольников: поскольку для любого квадрата всегда можно указать прямоугольник, который ведет себя абсолютно так же (обе стороны которого равны стороне квадрата, очевидно), то, согласно Лисков, квадрат является подтипом прямоугольника)до тех пор, пока клиентский код не будет надеяться на то, что изменение высоты прямоугольника не приводит к изменению его ширины.
ЗЫ дежавю )))
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959736
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
l s p начинаю пониматьtchingizне согласен.
в теле программы x заменим на 1.
упростим. параметр не нужен
Код: plaintext
float half() { return  1 . 0 / 2 ; }
и
Код: plaintext
float half() { return  1 / 2 ; }

вернут разные результаты
Так вы не объект заменили, вы программу (функцию) изменили. Вообще, с чего вдруг второй вариант написан "in terms of int", а не "in terms of float"?
))
я выполнил substitution, и o1 is substituted for o2,
дале я жду, что бы поведение программы было неизменным.

the behavior of P is unchanged

поскольку поведение программы до субститушион и после отличаются, то \
делаю вывод, что int не есть подтип float/
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959737
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
l s p начинаю пониматьК чему переопределять-то? Что, операция деления двух целых чисел не такая, как для деления двух рациональных? Чему противоречит то, что результат будет нецелым? Вы же сами себя в рамки замкнутости относительно деления и загоняете, а потом говорите что раз эти рамки есть то наследование невозможно))ещё раз: чему будет равно значение переменной с в таком случае: int c = half( 1 ); ???
операция деления целых чисел должно возвращать целое число.
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959739
egorychдо тех пор, пока клиентский код не будет надеяться на то, что изменение высоты прямоугольника не приводит к изменению его ширины.
ЗЫ дежавю )))
Вы опять про переопределенные методы (сеттеры). Нельзя их использовать, если хотите применять принцип Лисков, вот и вся задача. И это вовсе не значит, что "квадрат с переопределенными сеттерами сторон не является подтипом прямоугольника согласно LSP". Это значит лишь то, что данный вопрос неразрешим при помощи LSP, ни в ту ни в другую сторону.
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959747
Фотография ZyK_BotaN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychl s p начинаю пониматьК чему переопределять-то? Что, операция деления двух целых чисел не такая, как для деления двух рациональных? Чему противоречит то, что результат будет нецелым? Вы же сами себя в рамки замкнутости относительно деления и загоняете, а потом говорите что раз эти рамки есть то наследование невозможно))ещё раз: чему будет равно значение переменной с в таком случае: int c = half( 1 ); ???
операция деления целых чисел должно возвращать целое число.

с каких это пор? это вы почерпнули из си-подобных языков(дак там результат деления не цлое, вас ввело в заблуждение то что операция деления и деления нацело обозначаеться одним оператором "/")? Например: в пскале при делении целого на целое ответ рациональный, в 3-м питоне тоже деление не цлеочисленное , интересно почему это зделали? :) наврное они незнали что в результат деления целых это целое.
в случае int c = half( 1 ); - необходимо зделать приведение типов. с каких это пор обьект базового класса присваевался ссылке производного?
...
Рейтинг: 0 / 0
Наследование(ООП). растолкуйте
    #35959751
tchingiz))
я выполнил substitution, и o1 is substituted for o2,
дале я жду, что бы поведение программы было неизменным.
the behavior of P is unchanged
поскольку поведение программы до субститушион и после отличаются, то \
делаю вывод, что int не есть подтип float/
{ return 1/2; } и { return 1.0/2; } - разные программы, хотя бы только потому что приводят к разным результатам, так что отрицать это бессмысленно;
заменить объект o2 на o1 в программе P значит вместо P(o2) выполнить P(o1).
А вы вместо P1() выполняете P2(). Нет никаких сомнений в том, что разные программы могут иметь разное поведение)))

egorychещё раз: чему будет равно значение переменной с в таком случае: int c = half( 1 ); ???
0.5, конечно же.
egorychоперация деления целых чисел должно возвращать целое число.
Ну кто вам такое сказал-то? Кому она это должна?
Это называется "порочный круг" в логике; вы требуете, чтобы деление было замкнуто для целых чисел, а потом сетуете на то, что он возвращает не те результаты, что для рациональных; ну а функция проверки числа на ноль - она-то имеет тип bool, а почему же не тип int для целых и не тип float для вещественных? чем она лучше или хуже функции взятия половины числа, а?
...
Рейтинг: 0 / 0
25 сообщений из 120, страница 3 из 5
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Наследование(ООП). растолкуйте
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]