![]() |
Модераторы: группа: Модератор, группа: Комодератор |
![]() ![]() ![]() |
|
DeadSoul |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1217 Регистрация: 25.9.2005 Где: Москва |
Извините, более подходящего раздела не увидел.
Ответ на вопрос ЗНАЮ. Знающие ответ пусть помолчат, а новички попробуют на него ответить. Дано: нужно реализовать два класса Square(квадрат) и Rectangle(прямоугольник). Понятно, что они очень похожи. Какой класс следует унаследовать от другого(или не нужно наследовать вообще ![]() -------------------- Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". Бьем спамеров их же оружием. Пусть весь спам сыпется им [email protected] |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich |
DeadSoul, тут от одного флейма очухаться не успели, а ты новый затеваешь?
![]() Ignat, убери тему от греха подальше! ![]() -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
DeadSoul |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1217 Регистрация: 25.9.2005 Где: Москва |
Void, не понял. При чем тут флейм? К тематике сайта вопрос имеет совсем прямое отношение
И вопрос на самом деле очень хороший. -------------------- Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". Бьем спамеров их же оружием. Пусть весь спам сыпется им [email protected] |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich |
DeadSoul, я вот эту тему имею в виду. Если здесь начнется продолжение, увольте.
-------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев |
ответа тут нет
это полностью зависит от контекста задачи если очень хочется наследовать и при этом получить как можно более общий ответ, то - наследовать от класса "фигура" ![]() то, что квадрат является прямоугольником в геометрическом смысле, ещё не значит, что он будет являться ним в той модели, которая будет описана в программе причина простая - в программе объекты могут меняться, в геометрии и математике вообще величины не меняются с другой стороны, в большинстве популярных языков, мягко говоря, не принято, чтобы объект менял свой класс вот и получается, что объект прямоугольник, скорее всего будет иметь методы SetWidth и SetHeight если квадрат наследовать от прямоугольника, то наличие в нём этих методов будет некорректным (по крайней мере, мне так кажется) - функции, получающие на вход прямоугольник вправе ожидать, что они могут сделать соотношение сторон любым если прямоугольник наследовать от квадрата... ну не знаю... если функция требует квадрат, то наличие возможности передать туда прямоугольник лично для меня выглядит несколько опасным... возможно, если работать с константными объектами (как это происходит в математике), т.е. запретить им менять свои параметры, можно было бы наследовать квадрат от прямоугольника... впрочем, это - то, о чём я говорил - зависимость от контекста задачи... чем не подходит "Философия программирования"? как мне кажется, туда можно было бы скинуть и тему, породившую этот вопрос, если бы из неё не устроили религиозную войну... Добавлено @ 00:39 например, Майерс (если не ошибаюсь) вообще не советует наследовать что-либо от конкретных классов часто более удобно выделить то общее, что мы в них видим, в абстрактный класс и наследовать от него... -------------------- qqq |
|||
|
||||
Quadr0 |
|
|||
Unregistered |
...
Это сообщение отредактировал(а) Quadr0 - 15.7.2011, 11:15 |
|||
|
||||
chipset |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US |
А ещё можно сделать шаблон Quad и вводить зависимости между сторонами стратегиями. К примеру:
quad<figures::rectangle> rect; quad<figures::square> sq; quad<figures::rhombus> rh; Где классы figures:: обозначают геометрические правила для сторон. А ещё можно создать класс polygon и определять там количество вершин и опять-же, зависимости. polygon<4, figures::square> sq; Я даже могу предположить проверку совместимости кол-ва сторон с выбранной моделью, используя шаблоны можно такого понатворить! И хотя это не ООП а АОП и в реальном проекте я вряд-ли такое буду практиковать, теоретически выглядит гламурно ![]() --------------------
|
|||
|
||||
Exception |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 4525 Регистрация: 26.12.2004 |
Либо вообще не определять квадрат (а зачем?), либо определить классы Квадрат и Прямоугольник производными от Четырёхугольника и предоставить в Квадрате метод ToRectangle(), либо попытаться реализовать вариант, предложенный Чипсетом.
|
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск |
Опять - двадцать пять?
![]() В самом деле, у квадрата лучше реализовать свойство "размер", который будет хранить в единственном экземпляре расстояние между двумя связанными вершинами, а прямоугольник уже наследовать от параллелограмма... Впрочем, что общего у квадрата и прямоугольника? Прямой угол между сторонами каждого угла? Так изменение параметров отличается.. Зачем наследовать одно от другого? О! Квадрат - от ромба, а прямоугольник - от паралелограмма, все они - от четырёхугольника, который просто хранит положение вершин и производит масштабирование(без нарушения пропорций). Т.е.: /---------- ромб --------------- квадрат --- четырёхугольник---| \______ параллелограмм ---------- прямоугольник |
|||
|
||||
ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь |
skyboy, к вашему сведению Ромб --- это параллелограмм
|
|||
|
||||
Exception |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 4525 Регистрация: 26.12.2004 |
И что? Это не значит, что наследоваться имеет смысл.
|
|||
|
||||
DeadSoul |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1217 Регистрация: 25.9.2005 Где: Москва |
maxim1000 ответил на вопрос правильно. Тут наследовать одщно от другого нельзя. Аналогично нельзя наследовать и все предложенные выше классы.
1. Наследовать прямоугольник от квадрата нельзя. Очевидно. 2. Почему нельзя наследовать квадрат от прямоугольника:
данный код корректен для прямоугольника, но некорректен для квадрата. Наилучший выход - реализация квадрата через прямоугольник, используя делегирование -------------------- Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". Бьем спамеров их же оружием. Пусть весь спам сыпется им [email protected] |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich |
Учитывая, что LSP нарушается в данном примере только при наличии изменяющих объект операций, нельзя ли вместо делегирования обойтись такой иерархией? ImmutableRectangle Rectangle : ImmutableRectangle ImmutableSquare : ImmutableRectangle Square : ImmutableSquare Несколько надуманно с практической точки зрения, но, с другой стороны, необходимость выделять квадрат в отдельный класс тоже совсем не очевидна. Хотя сам пример (равно как и круг/эллипс, действительное/комплексное число и т.д.) — превосходен. Это сообщение отредактировал(а) Void - 20.5.2006, 01:26 -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
maxim1000 |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев |
опять же с поправкой, что размеры можно изменять без возможности изменения размеров квадрат является прямоугольником...
не в курсе, что такое делегирование... типа наследования реализации (private в C++)? тогда не всегда стоит - квадрату нужно меньше данных для описания, чем прямоугольнику, так что получится неоправданая трата времени но "не стоит" здесь значит, что путь неоптимальный с точки зрения ресурсов, и при их нехватке лучше так не делать...
пожалуй, это определённо лучше дргих вариантов (разве что найдётся функция, которая решит использовать неизменяемость фигуры, передаст её куда-то, там выяснят, что она изменяемая и изменят, но я гоню из головы такие мысли - тут уже вопрос, как лучше назвать, чтобы было ясно, что он не неизменяемый, а функции его изменения недоступны) -------------------- qqq |
||||
|
|||||
chipset |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US |
Честно говоря, я бы не наследовал ничего вообще. ООП это хорошо, но читабельность тоже рулит и если придется поступится ООПом то я положу его на алтарь читабельности без малейшего промедления.
--------------------
|
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск |
ivashkanet, да ну? ![]() ![]() |
|||
|
||||
DeadSoul |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1217 Регистрация: 25.9.2005 Где: Москва |
-------------------- Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". Бьем спамеров их же оружием. Пусть весь спам сыпется им [email protected] |
||||
|
|||||
Exception |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 4525 Регистрация: 26.12.2004 |
Как я уже сказал, либо вообще лучше не наследовать (предоставив метод ToRectangle() у квадрата), либо использовать стратегии, как говорил Чипсет, либо пользовать вариант Войда, который мне тоже нравится.
|
|||
|
||||
Се ля ви |
|
|||
![]() Java/SOAрхитектор ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space |
Квадрат - частный случай прямоугольника, прямоугольник, соответственно, более общий. Квадрат можно описать длиной одной его стороны, а прямоугольник - длинами двух его сторон, имеющих различную длину.
Поэтому с точки зрения эффективного использования ресурсов прямоугольник должен быть наследником квадрата, т.к квадрат проще прямоугольника. Я оптимальную схему считаю что-то типа такой: Квадрат | длина ребра | |- Прямоугольник длина ребра длина ребра2 Это сэкономит память, поскольку представлять квадрат как прямоугольник с одинаковыми длинами рёбер будет не рационально с точки зрения оптимизации памяти - налицо дублирование данных. С другой стороны, логически прямоугольник - не есть квадрат и у нас страдает логическая структура. При преобразовании
Для того, что бы разрулить данное противоречие, действительно нужно ориентироваться на конкретную задачу и на язык программирования. Но если уж заранее сказать ничего конкретного мы не можем, могу предложить такой вариант: имплементировать длины рёбер (вообще-то это всегда рекомендуется делать) и сыграть на их представлении в памяти. Можно задать в Прямоугольнике методы, которые возвращают оба ребра - первое и второе и в квадрате интерфейс будет тот же самый, но метод, возвращающий второе ребро будет перегружен и реально будет вызывать метод первый, и только первый метод будет возвращать длину первого ребра. Тогда получаем оптимальный компромиcс. Единственное, что не очень красиво - это всплывающая проблема именования рёбер - их четыре, но реально отличаются из них в прямоугольнике - 2, а в квадрате - вообще только одно уникальное ребро в плане длины, так что если нам нужно установить длину ребра, то нам лучше реализовать методы "верниГоризонтальноеРебро" и "верниВертикальное". P.S. Впрочем, вся эта модель заметно усложняется, если нам понадобиться создавать всё дерево наследования объектов Планиметрии, а не только эти два, хотя и можно при этом действовать похожим способом. Это сообщение отредактировал(а) Се ля ви - 20.5.2006, 15:32 -------------------- |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Песочница | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |