В чем разница между типом и классом?
Что отличает тип от класса и наоборот?
(В общеязыковом смысле)
22 ответа
Следующий ответ взят из книги Gof (Design Patterns)
Класс объекта определяет, как объект реализован. Класс определяет внутреннее состояние объекта и реализацию его операций.
Напротив, тип объекта относится только к его интерфейсу - на набор запросов, на которые он может ответить.
Объект может иметь много типов, а объекты разных классов могут иметь один и тот же тип.
//example in c++
template<typename T>
const T & max(T const & a,T const &b)
{
return a>b?a:b; //> operator of the type is used for comparision
}
Для функции max требуется тип с операцией> со своим собственным типом, поскольку один из ее интерфейсов любого класса, который удовлетворяет вышеуказанному требованию, может использоваться для генерации конкретной функции max для этого класса.
Я всегда думаю о "типе" как о всеобъемлющем термине "классы" и "примитивы".
int foo; // Type is int, class is nonexistent.
MyClass foo; // Type is MyClass, class is MyClass
Вдохновленный Википедией...
В терминах теории типов;
Тип - это абстрактный интерфейс.
Типы, как правило, представляют собой существительные, такие как человек, место или вещь, или что-то номинализованное,Класс представляет реализацию типа.
Это конкретная структура данных и набор подпрограммРазличные конкретные классы могут создавать объекты одного абстрактного типа (в зависимости от системы типов).
* Например, можно реализовать тип
Stack
с двумя классами:SmallStack
(быстро для небольших стеков, но плохо масштабируется) иScalableStack
(хорошо масштабируется, но с большими накладными расходами для небольших стеков). *Точно так же данный класс может иметь несколько разных конструкторов.
Банановый пример.
Banana
Тип будет представлять свойства и функциональность бананов в целом.
ABCBanana
а такжеXYZBanana
классы будут представлять способы производства бананов.
(Различные поставщики бананов в реальной жизни, или разные структуры данных и функции для представления и рисования бананов в видеоигре).
ABCBanana
Затем класс может производить определенные бананы, которые являются примерамиABCBanana
класс, они будут объектами типа банан.
Нередко программист предоставляет единственную и единственную реализацию для типа. В этом случае имя класса часто совпадает с именем типа. Но есть еще тип (который может быть извлечен в интерфейсе при необходимости) и реализация (которая реализует отдельный интерфейс), которая создает экземпляры (объекты) класса.
Тип - это общий термин для всех доступных шаблонов объектов или концепций. Класс является одним из таких шаблонов объектов. Так же как тип структуры, тип Integer, тип интерфейса и т. Д. Это все типы
Если вы хотите, вы можете посмотреть на это так: тип является родительским понятием. Все остальные понятия: класс, интерфейс, структура, целое число и т. Д. Унаследованы от этого понятия.
Взято из цитирования GoF снизу:
Класс объекта определяет, как объект реализован. Класс определяет внутреннее состояние объекта и реализацию его операций.
Напротив, тип объекта относится только к его интерфейсу - на набор запросов, на которые он может ответить.
Я хочу привести пример с использованием Java:
public interface IType {
}
public class A implements IType {
public A{};
}
public class B implements IType {
public B{};
}
Оба класса A
а также B
реализовать интерфейс и, следовательно, имеют тип IType
, Кроме того, в Java оба класса создают свой собственный тип (соответственно своему имени класса). Таким образом, класс A
имеет тип A
а также IType
и класс B
имеет тип B
а также IType
удовлетворение:
Объект может иметь много типов, а объекты разных классов могут иметь один и тот же тип.
Разница между подтипами и подклассом, вероятно, также помогает понять эту проблему:
https://www.cs.princeton.edu/courses/archive/fall98/cs441/mainus/node12.html
В общеязыковом смысле - Класс - это реализация Типа.
Часто, когда это единственная реализация этого типа, вы можете использовать оба термина для ссылки на него в некотором контексте.
Напротив, например, в контексте C# - класс является лишь одной из многих реализаций концепции типа, таких как примитивы, структуры, указатели и т. Д.
Чтобы проиллюстрировать это самым быстрым способом:
Структура - это Тип, но Структура - это не Класс.
Как видите, тип - это "абстрактный" термин для обозначения не только определений классов, но также структур и примитивных типов данных, таких как float, int, bool.
Тип концептуально является надмножеством класса. В более широком смысле класс является одной из форм типа.
С классами тесно связаны интерфейсы, которые можно рассматривать как особый вид классов - чисто абстрактный. Это тоже типы.
Таким образом, "тип" охватывает классы, интерфейсы и в большинстве языков примитивы тоже. Кроме того, платформы, такие как CLR в dot-net, также имеют структурные типы.
Тип содержит описание данных (т.е. свойства, операции и т. Д.),
Класс - это определенный тип - это шаблон для создания экземпляров объектов.
Строго говоря, класс - это особая концепция, его можно рассматривать как пакет, содержащий подмножество метаданных, описывающих некоторые аспекты объекта.
Например, в C# вы можете найти интерфейсы и классы. Оба они являются типами, но интерфейс может определять только некоторый контракт и не может быть создан в отличие от классов.
Проще говоря, класс - это специализированный тип, используемый для инкапсуляции свойств и поведения объекта.
Википедия может дать вам более полный ответ:
Я думаю о типе как о множестве вещей, которые вы можете сделать с определенным значением. Например, если у вас есть целочисленное значение, вы можете добавить его к другим целым числам (или выполнить другие арифметические операции) или передать его функциям, которые принимают целочисленный аргумент. Если у вас есть значение объекта, вы можете вызывать методы, которые определены его классом.
Поскольку класс определяет, что вы можете делать с объектами этого класса, класс определяет тип. Класс - это нечто большее, поскольку он также предоставляет описание того, как реализованы методы (что-то, что не подразумевается типом) и как размечены поля объекта.
Также обратите внимание, что значение объекта может иметь только один класс, но оно может иметь несколько типов, поскольку каждый суперкласс предоставляет подмножество функциональных возможностей, доступных в классе объекта.
Таким образом, хотя объекты и типы тесно связаны, они на самом деле не одно и то же.
Типы в C, такие как Int Float, char и т. Д., Определяют данные, к которым можно обращаться с помощью определенных методов, которые могут с ними работать. Это не сложнее, чем это. Как для int я могу добавить, вычесть умножить и, возможно, делить. Это мои методы (или операции) для int. Класс - это просто определение нового типа. Сначала я определяю, как выглядят данные. Может быть, это один бит. Может быть, это два слова, как комплекс с реальной и мнимой частью. Или, может быть, это сложная штука с 309734325 байтами, представляющими атомную структуру странной частицы на Юпитере. Мне все равно Как целое число, я выполняю операции, которые могу выполнять с этим новым типом данных. В случае целого числа, которое я добавил, вычел и т. Д. С помощью этого нового типа данных я могу определить любые операции, которые я считаю целесообразными. Они могут быть добавлены вычитать и т.д., но они могут добавить другие вещи. Это те методы, которые я решил добавить в свой класс.
Суть в том, что с типом в C у вас есть определение того, что это за данные, т.е. байт, слово, число с плавающей запятой, символ и т. д. Но любой из них также подразумевает, какие операции являются законными и будут давать надежные результаты.
Класс ничем не отличается, кроме вас самих определить интерфейс и допустимые операции. Класс определяет эти вещи, и когда вы создаете его экземпляр в Object, он определяет поведение объекта точно так же, как определение типа определяет поведение целого числа при работе с ним.
Классы просто дают вам гибкость в определении новых типов и всего о том, как они работают.
Как только это определено, каждый раз, когда я создаю экземпляр объекта класса "thingy", он имеет определенную структуру данных и операции (методы), которые, как я сказал, вы можете делать с ним. Класс "вещь" явно не более или менее, чем новый тип, который C++ позволяет мне определять.
Чтобы добавить еще один пример различия: в C++ у вас есть указатель и ссылочные типы, которые могут ссылаться на классы, но сами по себе не являются классами.
Bar b; // b is of type "class Bar"
Bar *b2 = &b; // b2 is of type "pointer to Class Bar"
Bar &b3 = b; // b3 is of type "reference to Class Bar"
Bar *b4[7]; // b4 is of type "7-element array of pointers to Class Bar"
Bar ***b5; //b5 is of type "pointer to a pointer to a pointer to Class Bar"
Обратите внимание, что задействован только один класс, но можно использовать почти бесконечное число типов. В некоторых языках функции считаются "первоклассными объектами", и в этом случае тип функции является классом. В других тип функции является просто указателем. Классы, как правило, имеют концепцию способности хранить данные, а также операции с этими данными.
Мои мысли в значительной степени соответствуют ответу Аку.
Я рассматриваю классы как шаблон для создания объектов, а типы - это способ классификации этих объектов и предоставления нам интерфейса к ним.
Python также добавляет метаклассы, которые являются просто механизмом для создания классов, точно так же, как классы создают объекты (и хорошо, и классы, и метаклассы являются объектами).
Этот ответ на тот же вопрос в Lamba Ultimate кажется мне идеальным объяснением.
Тип обычно относится к классификации примитивных значений - целых чисел, строк, массивов, логических значений, значений NULL и т. Д. Обычно вы не можете создавать какие-либо новые типы.
Класс относится к именованному набору свойств и методов, с которым связан объект при его создании. Обычно вы можете определить столько новых классов, сколько захотите, хотя на некоторых языках вам нужно создать новый объект, а затем добавить к нему методы.
Это определение в основном верно, но некоторые языки пытались комбинировать типы и классы различными способами, что приводило к различным полезным результатам.
Типы и классы связаны, но не идентичны. Я предполагаю, что классы используются для наследования реализации, тогда как типы используются для замены во время выполнения.
Вот ссылка, объясняющая принцип подстановки и почему подклассы и подтипы не всегда одно и то же (например, в Java). Страница википедии о ковариации и контравариантности содержит больше информации об этом различии.
В таких языках, как Haskell, концепции класса не существует. В нем есть только типы. (И Type Class . Не путать с Class , Type Class - это скорее абстрактная версия Type).
Монада - это класс типа .
class Monad m where
(>>=) :: m a -> ( a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
С точки зрения (чистого) функционального программирования тип более фундаментален, чем класс, поскольку его корень можно проследить до теории типов (например, с точки зрения PTL лямбда-исчисление с типами и без типов ведет себя совершенно иначе), в то время как класс на самом деле является просто конструкцией. для включения OO.
В языках, которые поддерживают только Type и не поддерживают Class, функции часто рассматриваются как первоклассные.
Между тем, когда язык делает различие между типом и классом, функции - это скорее граждане второго сорта, которые могут быть прикреплены к объектам и т. Д. И да, часто вы можете прикрепить функцию к самому классу (также известную как статическая функция) .
Очевидно, что, поскольку есть языки с системой типов, которые не являются языками программирования ОО, тип должен быть более широким понятием, чем класс.
Даже на таких языках, как Java, int
является (примитивным) типом, но не классом.
Следовательно: каждый класс является типом, но не каждый тип является классом.
Интересный вопрос. Я думаю, что ответ аку на месте. Взять джава ArrayList
класс в качестве примера
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Экземпляр ArrayList
класс называется типом каждого расширяемого суперкласса и каждого реализуемого им интерфейса. Таким образом, экземпляр ArrayList
класс имеет тип ArrayList
, RandomAccess
, Cloneable
, и так далее. Другими словами, значения (или экземпляры) принадлежат одному или нескольким типам, классы определяют, что это за типы.
Различные классы могут описывать один и тот же тип.
Тип состоит из следующих частей:
- Операции = синтаксис
- Описание операций = семантика
Класс состоит из следующих частей:
- Операции = синтаксис
- Реализация (= различные реализации описывают одну и ту же семантику)
Некоторые заметки:
Интерфейс (как в Java) не является типом, потому что он не описывает семантику (описывает только синтаксис)
Подкласс не является подтипом, поскольку подкласс может изменить семантику, определенную в суперклассе, подтип не может изменить семантику супертипа (см. Принцип замещения Лискова, например, этот пример LSP).
Если мы подумаем над этим вопросом в контексте C#, мы дойдем до следующего ответа.
Система типов C# подразделяется на следующие категории:
Типы значений:
- Простые типы: как int, long, float и т. Д.
- Типы перечислений
- Типы структур
- Обнуляемые типы
Типы ссылок:
- Типы классов
- Типы интерфейса
- Типы массивов
- Типы делегатов
Как вы можете видеть, в C# существует много типов, класс которых является только одним из них. Есть только одно важное замечание: система типов C# унифицирована так, что значение любого типа может рассматриваться как объект. Каждый тип в C# прямо или косвенно происходит от типа класса объекта, а объект является основным базовым классом всех типов. Значения ссылочных типов обрабатываются как объекты, просто просматривая значения как объект типа. Значения типов значений обрабатываются как объекты, выполняя операции упаковки и распаковки.
так что, как я вижу, type является зонтиком для многих элементов, класс которых является одним из них.
Ссылка: Документация по спецификации языка CSahrp, стр. 4
Это был хороший вопрос для меня, который заставил меня задуматься. Я бы осмелился сказать, что Class - это штука во время компиляции, а Type - штука во время выполнения. Я говорю это потому, что вы пишете классы, а не типы. Затем компилятор создает типы из классов, а среда выполнения использует типы для создания экземпляров объектов.
типы - это программные конструкции, которые помогают компилятору выполнять проверку типов и обеспечивать правильные свойства переменных для операции.
классы - это определяемые пользователем типы, которые могут иметь ссылающиеся на них объекты или переменные. Они также проходят проверку типа.