Наследование или состав: Полагайтесь, “-”, и “имеет - a”?

Сильная типизация, вероятно, означает, что переменные имеют четко определенный тип и что существуют строгие правила объединения переменных разных типов в выражениях. Например, если A является целым числом, а B является float, то строгим правилом относительно A + B может быть то, что A передается в float, а результат возвращается как float. Если A является целым числом, а B является строкой, то строгим правилом может быть то, что A + B недействителен.

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

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

И обратите внимание, что, когда я использую слово «вероятно», это потому, что не существует общепринятых определений этих терминов. Как вы уже видели из ответов до сих пор.

Проще говоря так: на статически типизированном языке тип static , что означает, когда вы установите переменную на типа, вы НЕ МОЖЕТЕ изменить его. Это связано с тем, что типизация связана с переменной, а не с ее значением.

Например, в Java:

String str = "Hello";  //statically typed as string
str = 5;               //would throw an error since java is statically typed

Если на динамически типизированном языке тип dynamic , то есть после того, как вы установите переменную типа, вы можете ее изменить. Это связано с тем, что типизация связана со значением, а не с переменной.

Например, в Python:

str = "Hello" # it is a string
str = 5       # now it is an integer; perfectly OK

С другой стороны, сильная / слабая типизация на языке связанные с неявными преобразованиями типов (частично взятые из ответа @ Dario):

Например, в Python:

str = 5 + "hello" 
# would throw an error since it does not want to cast one type to the other implicitly. 

, тогда как в PHP:

$str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0 
// PHP is weakly typed, thus is a very forgiving language.

Статическая типизация позволяет проверять правильность типа во время компиляции. Статически типизированные языки обычно скомпилированы, и интерпретируются языки с динамическим типизированием. Поэтому динамически типизированные языки могут проверять ввод текста во время выполнения.

28
задан Federico A. Ramponi 17 January 2009 в 18:12
поделиться

9 ответов

Нет - "", не всегда приводит к наследованию. Хорошо приведенным примером являются отношения между квадратом и прямоугольником. Квадрат является прямоугольником, но это будет плохо для разработки кода, который наследовал Квадратный класс от Прямоугольного класса.

Мое предложение должно улучшить Ваш, "/имеет" эвристику с принцип замены Лисков . Чтобы проверить, выполняют ли отношения наследования принцип замены Лисков, спросите, могут ли клиенты базового класса воздействовать на sub класс, не зная, что это воздействует на sub класс. Конечно, все свойства sub класса должны быть сохранены.

В квадрате / прямоугольный пример, мы должны спросить, может ли клиент прямоугольника воздействовать на квадрат, не зная, что это - квадрат. Все, что должен знать клиент, - то, что это воздействует на прямоугольник. Следующая функция демонстрирует клиент, который предполагает, что установка ширины прямоугольника оставляет высоту без изменений.

void g(Rectangle& r)
{
    r.SetWidth(5);
    r.SetHeight(4);
    assert(r.GetWidth() * r.GetHeight()) == 20);
}

Это предположение верно для прямоугольника, но не для квадрата. Таким образом, функция не может воздействовать на квадрат, и поэтому отношения наследования нарушают принцип замены Лисков. (По тому, как - пример прибыл из битая ссылка . Другие примеры )

36
ответ дан ruohola 14 October 2019 в 10:48
поделиться

Да и нет.

грань может быть стерта. Этому не помогли некоторые довольно ужасные примеры программирования OO с первых лет OO как: менеджер является Сотрудником, Человек.

вещь, которую необходимо помнить о наследовании: наследование повреждает инкапсуляцию. Наследование является деталью реализации. Существуют все виды, записанные на этом предмете.

самый содержательный способ подвести итог его:

Предпочитают состав.

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

8
ответ дан cletus 14 October 2019 в 10:48
поделиться

Я не думаю, что это столь же просто, как "-" по сравнению с, "имеет -" - как cletus сказал, строка может стать очень расплывчатой. Это не похоже на двух человек, всегда приходил бы к тому же заключению, данному просто что как инструкция.

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

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

3
ответ дан Jon Skeet 14 October 2019 в 10:48
поделиться

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

Примеры:

  • при использовании защищенного или частного наследования тогда Вы теряете внешнюю замещаемость, то есть, насколько любой за пределами Вашей иерархии обеспокоен, что Полученным не является тип Основы.
  • при переопределении основного виртуального участника и поведения изменения, заметного от кого-то ссылающегося на Основу, от исходного Базового внедрения, тогда Вы эффективно повредили замещаемость. Даже при том, что у Вас есть общедоступная иерархия наследования Полученная Основа is-not-a.
  • Ваш класс может иногда быть substituitable для другого без любых отношений наследования на работе. Например, если необходимо было использовать шаблоны и идентичные интерфейсы для соответствующих функций членства константы тогда "Эллипс const&"; то, где Эллипс, оказывается, является совершенно круговым, могло быть substituitable для "Круга const&";.

, Что я пытаюсь сказать вот, это, берет длительное размышление, и работа для поддержания "-" substitutable отношения между двумя типами, используете ли Вы наследование или нет.

2
ответ дан nly 14 October 2019 в 10:48
поделиться

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

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

, Конечно, каждая ситуация уникальна, и нет никакого корректного способа принять это решение, только эмпирические правила.

1
ответ дан BigSandwich 14 October 2019 в 10:48
поделиться

Люди часто говорят, что наследование, "-" отношения, но это может получить Вас в проблему. Наследование в C++ разделяет на две идеи: повторное использование кода и определяющие интерфейсы.

первое говорит, что "Мой класс похож на этот другой класс. Я просто запишу код для дельты между ними и снова использую другую реализацию от другого класса так, как я могу".

второе зависит от абстрактных базовых классов и является списком методов, которые класс обещает реализовать.

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

1
ответ дан John D. Cook 14 October 2019 в 10:48
поделиться

No Да. Если отношения, "имеет -", использует состав. ( Добавленный : исходная версия вопроса сказала "наследование использования" для обоих - простая опечатка, но исправление изменяет первое слово моего ответа от "Нет" до "Да".)

И состав использования по умолчанию; только используйте наследование когда необходимый (но тогда используйте его).

1
ответ дан Jonathan Leffler 14 October 2019 в 10:48
поделиться

, Если отношения, "-" - наследование использования, и если отношения, "имеет -" - состав использования. Это всегда правильно?

В некотором смысле, да. Но необходимо бояться представлять ненужный, искусственный "-" отношения.

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

тем же способом, можно думать, что ThickBorder - специальная Граница, и используйте наследование; но лучше сказать, что Граница имеет - ширина, следовательно предпочитая состав.

Во всех этих неоднозначных случаях, мои эмпирические правила , думают дважды и, поскольку рекомендуемые другие, предпочитают состав по наследованию .

5
ответ дан Federico A. Ramponi 14 October 2019 в 10:48
поделиться

Мое эмпирическое правило (хотя не конкретный) - то, что, если я могу использовать тот же код для различных классов, тогда я поместил тот код в родительский класс и использую наследование. Иначе я использую состав.

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

-2
ответ дан Sam 14 October 2019 в 10:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: