Я новичок в дизайне и программировании OO, и у меня есть вопрос, который, я считаю, касается дизайна класса. Я буду настолько точным, насколько я могу в своей терминологии.Дизайн и наследование классов
[Изменить] Возможно, это сводится к следующему: у меня есть список объектов типа базового класса. Производные классы создаются как конкретные типы базового класса, реализующие методы базового класса, а некоторые с дополнительными параметрами и/или методами, специфичными для производного типа. Когда я пересекаю список, я работаю с базовым классом. Каким образом можно получить доступ к методам и параметрам для определенного варианта класса? Выключить инструкции и кастинг? Разве это не плохая форма на C# и не указывает на дефект в дизайне класса?
[Оригинал] Следуя примеру Строуступа в книге «Язык программирования на С ++», предположим, что я пишу графическую программу, использующую «форму» базового класса, и классы «круг», «треугольник», и «квадрат», которые получены из «формы». Согласно Stroustrup, базовый класс должен содержать функции-члены, необходимые для реализации «полного набора операций» для класса формы. В большинстве случаев эти функции-члены будут виртуальными, так что производные классы могут реализовать функциональные возможности, специфичные для их формы, такие как: загрузка, сохранение, рисование, поворот, обновление и т. Д. Это все имеет смысл для меня.
Где я сталкиваюсь с трудностями - это влияние тонких различий между типами фигур и последствиями этих различий в базовом классе. Например, рассмотрим функции-члены, специфичные для определенной производной формы. Предположим, что форма «круг» имеет значение, описывающее, сколько сегментов линии используется для приближения круга (например, lineCount). Как обрабатывать параметр и обновлять это значение таким образом, чтобы не начинать загрязнять мой базовый класс виртуальными функциями-членами, «пузыряться» от конкретных потребностей каждого из производных классов?
Я спрашиваю об этом, потому что ожидаю сохранить список типа «форма» для отслеживания всех моих объектов. Я не ожидаю наличия списков типов «круг», «треугольник» и «квадрат», где можно было бы получить прямой доступ к определенному значению lineCount для круга и не будет держать эти отдельные списки в любом случае нарушающим всю идею наследования неявно или явно вводя эквивалент оператора switch с случаями для каждого типа формы?
Чтобы решить эту проблему, я нахожусь на правильном пути, чтобы думать, что помимо очевидных функций-членов, таких как «рисовать», я должен глубоко подумать о требовании «полного набора операций». Поэтому, если у меня есть конкретное значение формы (например, lineCount для формы круга), оно должно быть возможным через функции-члены формы, чтобы получить/установить это значение в общем виде, совместимом с другими (возможно, разными) значениями из другого формы. Я могу только думать, что класс формы должен поэтому включать в себя общую функцию настройки параметров, которая может включать в себя требование, чтобы каждый производный класс представлял свою собственную форму пользовательского интерфейса, запрашивая ее конкретные параметры конкретной формы. Требование класса формы к включению функций-членов пользовательского интерфейса кажется, что класс формы становится слишком тяжелым.
Я думаю об этом правильно? Есть ли лучший способ обработать тонкие различия в производных классах?
Один из способов решения этой проблемы - иметь конфигурационные данные 'std :: map' (или' Dictionary' для C#) и виртуальную функцию 'configure', которую вы можете вызывать для передачи необходимых данных для каждого типа фигуры. –
Все подклассы должны реализовывать «полный набор операций» в базовом классе. Но это не означает, что базовый класс должен поддерживать все операции, которые может иметь любой подкласс. Просто поместите такие функции только в подкласс, который ему нужен. – user2079303
Zac, это ваш комментарий, связанный с решением конкретной проблемы ВСЕХ кругов, нуждающихся в значении lineCount, где значение одной строки, сохраненное в качестве параметра конфигурации, может применяться ко всем кругам. Если так, я верю, что понимаю, что вы говорите. Но моя проблема более общая, каждый конкретный тип формы имеет уникальные значения, которые уникальны для него в одиночку. Есть ли решение лучше, чем «Полный набор операций» или с помощью операторов casts/switch на объектах формы типа, хранящихся в списке? – BobC