Сильная типизация, вероятно, означает, что переменные имеют четко определенный тип и что существуют строгие правила объединения переменных разных типов в выражениях. Например, если 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.
Статическая типизация позволяет проверять правильность типа во время компиляции. Статически типизированные языки обычно скомпилированы, и интерпретируются языки с динамическим типизированием. Поэтому динамически типизированные языки могут проверять ввод текста во время выполнения.
Нет - "", не всегда приводит к наследованию. Хорошо приведенным примером являются отношения между квадратом и прямоугольником. Квадрат является прямоугольником, но это будет плохо для разработки кода, который наследовал Квадратный класс от Прямоугольного класса.
Мое предложение должно улучшить Ваш, "/имеет" эвристику с принцип замены Лисков . Чтобы проверить, выполняют ли отношения наследования принцип замены Лисков, спросите, могут ли клиенты базового класса воздействовать на sub класс, не зная, что это воздействует на sub класс. Конечно, все свойства sub класса должны быть сохранены.
В квадрате / прямоугольный пример, мы должны спросить, может ли клиент прямоугольника воздействовать на квадрат, не зная, что это - квадрат. Все, что должен знать клиент, - то, что это воздействует на прямоугольник. Следующая функция демонстрирует клиент, который предполагает, что установка ширины прямоугольника оставляет высоту без изменений.
void g(Rectangle& r)
{
r.SetWidth(5);
r.SetHeight(4);
assert(r.GetWidth() * r.GetHeight()) == 20);
}
Это предположение верно для прямоугольника, но не для квадрата. Таким образом, функция не может воздействовать на квадрат, и поэтому отношения наследования нарушают принцип замены Лисков. (По тому, как - пример прибыл из битая ссылка . Другие примеры )
Да и нет.
грань может быть стерта. Этому не помогли некоторые довольно ужасные примеры программирования OO с первых лет OO как: менеджер является Сотрудником, Человек.
вещь, которую необходимо помнить о наследовании: наследование повреждает инкапсуляцию. Наследование является деталью реализации. Существуют все виды, записанные на этом предмете.
самый содержательный способ подвести итог его:
Предпочитают состав.
, Который не означает, используют его для полного исключения наследования. Это просто означает, что наследование является положением нейтрализации.
Я не думаю, что это столь же просто, как "-" по сравнению с, "имеет -" - как cletus сказал, строка может стать очень расплывчатой. Это не похоже на двух человек, всегда приходил бы к тому же заключению, данному просто что как инструкция.
Также, поскольку cletus сказал, предпочтите состав по наследованию. По моему мнению должны быть действительно серьезные основания произойти из базового класса - и, в частности, базовый класс действительно должен быть , разработал для наследования, и действительно для вида специализации Вы хотите подать заявку.
Кроме того - и это, вероятно, будет непопулярной идеей - она снижается для дегустации и инстинктивное чувство. Со временем я думаю, что хорошие разработчики получают лучший смысл того, когда наследование будет работать и когда оно не будет, но им может быть трудно выразить ясно. Я знаю , мне трудно, как демонстрирует этот ответ. Возможно, я просто проектирую трудность на других людей хотя:)
Наследование не всегда означает, что существует, "-" отношения и отсутствие, каждый не всегда подразумевает, что нет.
Примеры:
, Что я пытаюсь сказать вот, это, берет длительное размышление, и работа для поддержания "-" substitutable отношения между двумя типами, используете ли Вы наследование или нет.
Я думаю, что John имеет верное представление. Ваше рассмотрение Ваших отношений класса как создание модель , которая является тем, что они пытаются заставить Вас делать, когда они начинают преподавать Вам принципалы ООП. Действительно, Ваш более обеспеченный взгляд на то, как вещи функционируют в терминах коды архитектура . Таким образом, что является лучшим способом для других программистов (или Вы), чтобы снова использовать Ваш код, не повреждая его или имеющий необходимость посмотреть на реализацию для наблюдения то, что это делает.
я нашел, что наследование часто повреждает идеал "черного квадрата", поэтому если сокрытие информации важно, это не может быть лучший способ пойти. Я все больше находил, что наследование лучше для обеспечения единого интерфейса, чем это для многократного использования компонентов в других местах.
, Конечно, каждая ситуация уникальна, и нет никакого корректного способа принять это решение, только эмпирические правила.
Люди часто говорят, что наследование, "-" отношения, но это может получить Вас в проблему. Наследование в C++ разделяет на две идеи: повторное использование кода и определяющие интерфейсы.
первое говорит, что "Мой класс похож на этот другой класс. Я просто запишу код для дельты между ними и снова использую другую реализацию от другого класса так, как я могу".
второе зависит от абстрактных базовых классов и является списком методов, которые класс обещает реализовать.
первое может быть очень удобным, но это может также вызвать проблемы обслуживания, если не преуспевший и таким образом, некоторые люди пойдут, говоря, что Вы никогда не должны делать этого. Большинство людей подчеркивает второе, использующее наследование для того, что другие языки явно называют интерфейсом.
No Да. Если отношения, "имеет -", использует состав. ( Добавленный : исходная версия вопроса сказала "наследование использования" для обоих - простая опечатка, но исправление изменяет первое слово моего ответа от "Нет" до "Да".)
И состав использования по умолчанию; только используйте наследование когда необходимый (но тогда используйте его).
, Если отношения, "-" - наследование использования, и если отношения, "имеет -" - состав использования. Это всегда правильно?
В некотором смысле, да. Но необходимо бояться представлять ненужный, искусственный "-" отношения.
, Например, можно думать, что ThickBorderedRectangle - Прямоугольник, который кажется разумным на первый взгляд, и решите использовать наследование. Но эта ситуация лучше описана, говоря, что Прямоугольник имеет - Граница, которая может или не может быть ThickBorder. В этом случае он лучше предпочел бы состав.
тем же способом, можно думать, что ThickBorder - специальная Граница, и используйте наследование; но лучше сказать, что Граница имеет - ширина, следовательно предпочитая состав.
Во всех этих неоднозначных случаях, мои эмпирические правила , думают дважды и, поскольку рекомендуемые другие, предпочитают состав по наследованию .
Мое эмпирическое правило (хотя не конкретный) - то, что, если я могу использовать тот же код для различных классов, тогда я поместил тот код в родительский класс и использую наследование. Иначе я использую состав.
Это заставляет меня писать меньше кода, который по сути легче поддержать.