Когда вы говорите «тип», я предполагаю, что вы в основном имеете в виду статический тип. Но вскоре я расскажу о динамических типах.
Статический тип - это свойство части программы, которое может быть статически доказано (статический означает «без запуска»). В статически типизированном языке каждое выражение имеет тип независимо от того, пишете вы его или нет. Например, в Cish «int x = a * b + c - d», a, b, c и d имеют типы, a * b имеет тип, a * b + c имеет тип и a * b + c -d имеет тип. Но мы только аннотировали х с типом. В других языках, таких как Scala, C #, Haskell, SML и F #, даже в этом нет необходимости.
Какие именно свойства доказуемы, зависит от средства проверки типов.
С другой стороны, класс стиля Scala - это просто спецификация для набора объектов. Эта спецификация включает некоторую информацию о типе и включает в себя множество деталей реализации и представления, таких как тела методов, закрытые поля и т. Д. В Scala класс также определяет границы некоторых модулей.
Многие языки имеют типы, но не имеют классов, и многие языки имеют классы, но не имеют (статических) типов.
Существует несколько наблюдаемых различий между типами и классами. List [String] - это тип, но не класс. В Scala List - это класс, но обычно это не тип (на самом деле это тип с более высоким родом). В C # List это не какой-либо тип, а в Java это «необработанный тип».
Scala предлагает структурные типы. {def foo: Bar} означает любой объект, который доказуемо имеет метод foo, который возвращает Bar, независимо от класса. Это тип, но не класс.
Типы могут быть абстрагированы с использованием параметров типа. Когда вы пишете def foo [T] (x: T) = ..., то внутри тела foo T есть тип. Но Т не класс.
Типы могут быть виртуальными в Scala (то есть «члены абстрактного типа»), но классы не могут быть виртуальными в Scala сегодня (хотя существует сложный способ кодирования виртуальных классов https://wiki.scala -lang.org / дисплей / SIW / VirtualClassesDesign )
Теперь динамические типы. Динамические типы - это свойства объектов, которые среда выполнения автоматически проверяет перед выполнением определенных операций. В динамически типизированных ОО-языках на основе классов существует сильная корреляция между типами и классами. То же самое происходит с языками JVM, такими как Scala и Java, в которых есть операции, которые можно проверять только динамически, такие как отражение и приведение. В этих языках «стирание типа» более или менее означает, что динамический тип большинства объектов совпадает с их классом. Более менее. Это не относится, например, к массивам, которые обычно не стираются, так что среда выполнения может показать разницу между Array [Int] и Array [String]. Но помните мое широкое определение «динамические типы - это свойства объектов, которые среда выполнения автоматически проверяет». При использовании отражения можно отправить любое сообщение любому объекту. Если объект поддерживает это сообщение, то все работает. Таким образом, имеет смысл говорить обо всех объектах, которые могут крякать, как утка, как о динамическом типе, даже если это не класс. Это суть того, что в сообществах Python и Ruby называют «типизацией утки». Кроме того, по моему широкому определению, даже «zeroness» является динамическим типом в том смысле, что в большинстве языков среда выполнения автоматически проверяет числа, чтобы убедиться, что вы не делите на ноль. Существует очень и очень мало языков, которые могут доказать это статически, делая ноль (или не ноль) статическим типом.
Наконец, как уже упоминали другие, есть такие типы, как int, у которых нет класса в качестве детали реализации, типы, такие как Null и Any, которые немного особенные, но могут иметь классы и не имеют, и типы, подобные Nothing который даже не имеет значений, не говоря уже о классе.