Класс и тип в чем разница
Перейти к содержимому

Класс и тип в чем разница

  • автор:

c# различия между классом и типом?

Правильно ли я понимаю: каждый класс это совокупность типов, а каждый тип это либо класс либо структура?

Отслеживать

13.7k 12 12 золотых знаков 43 43 серебряных знака 75 75 бронзовых знаков

задан 26 янв 2018 в 16:40

Dmitry Bocharov Dmitry Bocharov

109 6 6 бронзовых знаков

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

  • типы-значения — это структуры и перечисления ( enum ),
  • ссылочные типы — это классы, а также массивы, интерфейсы и делегаты,
  • типы-параметры — это типы, являющиеся параметрами обобщённых классов и методов (они не являются ни типами-значениями, ни ссылочными типами, и живут по особым правилам), и
  • типы-указатели (которые могут появляться лишь в unsafe -коде).

Каждый класс, в свою очередь, определяет структуру данных (не путать с struct !), содержащую

  • данные-члены: константы и поля,
  • функции-члены: методы, свойства, события, индексаторы, операторы, конструкторы объекта, деструкторы-финализаторы и статические конструкторы, и
  • вложенные типы.
  1. Класс не есть совокупность типов, а лишь определение для структуры данных-экземпляра (он же объект) типа. Определение содержит именованные и неименованные данные-члены, функции-члены и вложенные типы.
  2. Типами, кроме классов и структур, являются ещё и перечисления, массивы, интерфейсы, делегаты, типы-параметры и указатели.

Типы и классы: в чем разница?

Задался вопросом: что такое типы и что такое классы, в чем их отличие?

Вот тут пишут, что в c# http://www.intuit.ru/department/pl/csharp/3/ типы и классы это почти синонимы. А в хаскеле — классы типов. Т.е. это все-таки разные понятия?

anonymous
29.08.07 21:39:07 MSD

Re: Типы и классы: в чем разница?

может это как-то связано с понятиями «кассификация» и «типизация» ?

anonymous
( 29.08.07 21:42:57 MSD )
Ответ на: Re: Типы и классы: в чем разница? от anonymous 29.08.07 21:42:57 MSD

Re: Типы и классы: в чем разница?

Не претендую на правильность, но по-моему, в большинстве случаев клссы — подмножество типов. Т. е., например в C++ каждый класс является типом, однако обраное не обязательно.

Deleted
( 29.08.07 21:58:36 MSD )

Re: Типы и классы: в чем разница?

Это зависит от того, как определить понятия 🙂 В Си++ и Хаскеле они определены по-разному. AFAIK, общепринятого определения не существует.

tailgunner ★★★★★
( 29.08.07 22:09:28 MSD )
Ответ на: Re: Типы и классы: в чем разница? от Deleted 29.08.07 21:58:36 MSD

Re: Типы и классы: в чем разница?

> кассификация

Господа, поставьте уже спеллчекер 🙂

watashiwa_daredeska ★★★★
( 29.08.07 22:50:38 MSD )

Re: Типы и классы: в чем разница?

Неужели так сложно прочитать Бьёрна Страуструпа? К чему все эти гадания?

andreyu ★★★★★
( 30.08.07 03:55:50 MSD )

Re: Типы и классы: в чем разница?

Есть «классы C#». Есть «классы Хаскеля». «Классов» не существует.

Miguel ★★★★★
( 30.08.07 10:05:23 MSD )
Ответ на: Re: Типы и классы: в чем разница? от andreyu 30.08.07 03:55:50 MSD

Re: Типы и классы: в чем разница?

> Неужели так сложно прочитать Бьёрна Страуструпа?

. и газету «Московский комсомолец».

anonymous
( 30.08.07 11:12:51 MSD )

Re: Типы и классы: в чем разница?

Я уже об этом здесь писал, да ладно напишу еще раз.

На классы можно смотреть с 3-х позиций: класс-как-тип, класс-как-поведение и класс-как-интерфейс. Еще можно смотреть с позиции класс-как-объект, но не везде и не всегда.

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

Macil ★★★★★
( 30.08.07 12:03:35 MSD )
Ответ на: Re: Типы и классы: в чем разница? от Macil 30.08.07 12:03:35 MSD

Re: Типы и классы: в чем разница?

> Я уже об этом здесь писал, да ладно напишу еще раз.

очень интересно. можешь дать ссылку на развёрнутый ответ (местный поиск не рулит -) ), или если нетрудно, откомментировать тут еще раз?

subj интересует с точки зрения проектирования языка программирования: стоит-ли различать эти понятия и какой смысл в них вкладывать?

anonymous
( 30.08.07 15:39:11 MSD )
Ответ на: Re: Типы и классы: в чем разница? от andreyu 30.08.07 03:55:50 MSD

Re: Типы и классы: в чем разница?

спасибо за ссылку на Страуструпа =), но тут больше интересует концептуальная сторона вопроса, а не игра слов в конкретном ЯП. 🙂

anonymous
( 30.08.07 15:39:45 MSD )
Ответ на: Re: Типы и классы: в чем разница? от anonymous 30.08.07 15:39:45 MSD

Re: Типы и классы: в чем разница?

krum ★
( 30.08.07 17:01:52 MSD )
Ответ на: Re: Типы и классы: в чем разница? от anonymous 30.08.07 15:39:11 MSD

Re: Типы и классы: в чем разница?

>очень интересно. можешь дать ссылку на развёрнутый ответ

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

>стоит-ли различать эти понятия и какой смысл в них вкладывать

Немного не понял сути вопроса. Все три понятия взаимосвязаны, очень хороший схожий пример — структура белка (т.е. первичная влияет на вторичную, вторичная влияет на третичную). И по-моему разлчай их или не различай, ничего не изменится. Вот например, в эрланге объект это вообще легковесная нить и что тогда класс?

>какой смысл в них вкладывать

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

Object vs Type vs Class vs Instance

Описание связи между объектом, типом, классом и экземпляром в Python.

Объекты

Объекты — способ представления любых сущностей в Python. Все данные в Python представлены объектами и связями объектов. У каждого объекта есть идентификатор, тип и значение. Идентификатор (identity) никогда не меняется с момента создания объекта. Оператор is сравнивает идентификтаторы двух объектов; функция id() возвращает целочисленный идентификатор объекта.

Для CPython, id(x) — адрес памяти, где хранится x.

>>> a = 127 >>> b = 128 >>> id(a) 1465020576 >>> id(b) 1465020608 >>> a is b False 

В Python все — объект. Списки — это объекты. Строки, модули, функции — это объекты. Байткод программы хранится как объект. У всех объектов есть типы и идентификаторы:

>>> def dummy(): pass . >>> type(dummy), id(dummy) (, 2122090425880) >>> type(dummy.__code__), id(dummy.__code__) (, 2122094942368) >>> 

Модель “все — объект” прослеживается и в самой реализации CPython. В коде CPyton к любой сущности, упомянутой выше, можно обратиться через указатель на стркутуру PyObject.

Типы

У каждого объекта Python есть тип. Тип можно выяснить, вызвав “встроенную функцию” type() . Тип — это тоже объект, поэтому у него есть собственный тип, который называется type . Этот факт не слишком полезен для написания простого кода на Python, однако, он важен для понимания внутренностей CPython:

>>> type(42) >>> type(type(42)) >>> type(type(type(42)))

Все типы сходятся к type.

Классы

Давным-давно была разница между встроенными классами и пользовательскими классами, но с версии 2.2 (классы “нового стиля”, унаследованные от object в 2.x, и все классы в 3.x) значимых отличий нет. В сущности, класс это механизм Python, который позволяет создавать пользовательские типы в коде Python.

>>> class Snake: pass . >>> s = Snake() >>> type(s) >>> 

Используя этот механизм, мы создали Snake — пользовательский тип. s — экземпляр класса Snake. Или, другими словами, s — это объект, и его тип — Snake. Термины “class” и “type” оба ссылаются на одну концепцию.

Экземпляры (instance)

В отличие от неоднозначности терминов “класс” и “тип”, экземпляр — это синоним термина “объект”. Еще раз: объекты — это экземпляры типов. Так, “42 это экземпляр типа int” равносильно “42 — объект int”. Термин “экземпляр” используется во встроенной функции isinstance() .

В Python все — объект, поэтому любой пользовательский класс — это тоже объект, и его тип обычно “type”. Повторим еще раз: все пользовательские типы обычно являются экземплярами класса type.

На примере класса Snake:

>>> type(Snake)

Введем новый термин: Метакласс — это специальный класс, конструктор которого возвращает класс. То есть, связь метакласс->класс аналогична связи класс->объект. Тот факт, что классы являются экземплярами класса “type”, позволяет нам создавать свои метаклассы (классы, которые наследуются от класса “type” и конструктор которых возвращает класс).

>>> class TestMeta(type): pass # создаем простейший метакласс . >>> MyClass = TestMeta("myclass",tuple(),<>) # создаем экземпляр метакласса >>> MyClass >>> type(MyClass) # получили пользовательский класс c типом, отличным от type >>> type(type(MyClass))

Зачем? Как правило, метаклассы используют при написании сложных фреймворков уровня Django ORM, они позволяют вынести часть внутренней магии выше пользовательского кода, чтобы “пользователь” не вдавался в подробности реализации. Как метко заметил гуру питона Тим Питерс, Если вы сомневаетесь, надо ли вам их использовать — не надо.

Итог

Напрашивается наивный вопрос: так что же главнее — type или object?

>>> type.__bases__ (,) >>> object.__bases__ () 

type наследуется от object, но при этом же:

>>> type(object)

object имеет тип type. По сути, object — корень иерархии объектов, а type — корень иерархии типов. Каждый тип это объект, а у каждого объекта есть тип, этим и вызвана такая двойственность их определений. Среди них нет первоисточника, это единственное подобное исключение, заложенное в основу языка.

Рассмотрим на примере стандартных классов. Класс bool наследуется от класса int. На картинке наследование объектов показано зеленым, наследование типов — красным.

_config.yml

И добавим сюда классы из примеров выше:

_config.yml

Таким образом, метаклассы позволяют реализовать иерархию типов, подобную наследованию объектов. Практический смысл метаклассов — при создании класса мы можем выполнить произвольный код, который модифицирует создаваемый класс, без необходимости вносить изменения в сам класс (но в 99% случаев подобное лучше делать через декораторы классов/наследование).

Примечание

Следует отличать встроенную функцию isinstance() и оператор is :

isinstance(object, class) возвращает True, если object является экземпляром class , либо экземпляром класса, унаследованного от class .

Оператор is , в свою очередь, возвращает True, если две переменные ссылаются на один объект, т.е. сверяет идентификаторы объектов.

Динамическое создание классов через type()

Вместо вызова с одиним аргументом, type() можно вызвать с тремя:

type(classname, superclasses, attributes_dict)

Если type вызван с тремя аргументами, он вернет новый объект type . Это позволяет динамически формировать классы (как это сделано в примере с метаклассом):

  • “classname” — строка, которая определяет имя класса и становится его атрибутом __name__ ;
  • “superclasses” — это кортеж родительских классов, становится атрибутом __bases__ ;
  • “attributes_dict” — это словарь, представляющий пространство имен нашего класса. Он содержит определенние тела класса и становится его атрибутом __dict__ . Атрибутами класса могут быть любые объекты:
>>> m = type("mytype", (int,), ) >>> m.test 'field' >>> m.greet() hello word 

Иногда type() называют встроенной функцией, но надо понимать, что type(1), хоть и выглядит как print(1), на самом деле является вызовом констркутора типа type с одиним аргументом. Вызов конструктора с одним аргументом возвращает тип переданного объекта, с тремя — создает новый тип. Вот так выглядит сигнатура type.__init__() :

def __init__(cls, what, bases=None, dict=None): """ type(object_or_name, bases, dict) type(object) -> the object's type type(name, bases, dict) -> a new type """ . 

Чем отличается тип данных от класса?

В С++ можно написать
System::Int32 i = 1;
а можно
int i = 1;
чем эти 2 объявления отличаются? И зачем вообще тип данных, если есть классы (кроме удобства)?

класс — это полноценный класс со всеми вытекающими
primitive type — это вшитая в язык конструкция
не было бы примитивного инта, нельзя было бы написать класс-обертку
примитивные типы быстрее из-за отсутствия наворотов от класса

и занимают меньше места (как минимум, за счет возможного выравнивания).
и совместимы

речь идёт о MC++? Насколько я понимаю, так int и System::Int32 — это одно и то же, и Int32 является не классом (который — reference-type а value-type

> Чем отличается тип данных от класса?

В Haskell есть деление на классы и экземпляры (instance которого нет в ООП. Класс только определяет набор и сигнатуры методов, экземпляр только реализует их. Т. о. автоматически отпадает проблема множественного наследования. Классы не наследуют и не переопределяют методы других классов — каждый метод принадлежит только одному классу. Такой подход проще, чем сложная схема взаимоотношений классов в ООП. Некоторый тип данных может принадлежать нескольким классам; класс может требовать, чтобы каждый его тип обязательно принадлежал к другому классу, или даже нескольким; такое же требование может выдвигать экземпляр. Это аналоги множественного наследования. Есть и свойства, не имеющие аналогов в ООП. Например, реализация списков как экземпляра класса сравнимых величин требует, чтобы элементы списка также принадлежали к классу сравнимых величин.

class type и data type не перепутал?

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

ну да, а в жаве/шарпе классы и интерфейсы отличаются. Чудеса, да?

а класс там что такое?

А в питоне никаких типов уже давно нету, все структурные единицы — объекты какого-либо класса
Очень удобно, но язык довольно-таки прожорливый (я про память).

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

Да вот ситуацияпочти такая же, как в Хаскеле, только терминология другая. Интерфейс задаёт контракт, класс — определяет реализацию.

Сорри, не class type, a type class:
http://en.wikipedia.org/wiki/Type_class
Короче, хаскеловские классы — это совсем не то, что в ООП привыкли называть классами. Это классы типов, а не классы объектов. Нечто, напоминающее интерфейсы в языках типа джавы.

В языках типа С++, джавы и шарпа так сложилось исторически — есть примитивные заранее определенные типы, и есть более сложные сущности — классы. Где-то это наследство С (в котором есть int, но нет class Int где-то — проявление архитектуры VM. В некоторых ОО языках, например Руби, такого разделения нет: все — классы.
Кроме того, ООП-теоретики указывали на различия между понятиями класса и типа, которые
проявляются при сравнении subtyping и subclassing..

в таком случае, именно про разницу между typeclass и data type я и попытался написать.
в джаве вроде похоже, потому что объединять интерфейсы в одной реализации можно с помощью наследования.

(там цитата не моя а с викибукс. сорри, если там что-то не так, я ее понял именно так, как ты потом объяснил).

А есть в каком-нибудь ещё языке кроме питона такое понятие как метаклассы? Это типа конструктор классов, ну что-то вроде класса, объекты которого — классы.

template в C++? Generics в Java/C#? System.Type в .NET?

ну вот в хаскелле классы — это такие штуки, объекты которых — типы.

>А есть в каком-нибудь ещё языке кроме питона такое понятие как метаклассы? Это типа конструктор классов, ну что-то вроде класса, объекты которого — классы.
В Руби есть нечто похожее, вроде.
Правда, сходство в основном в названии. Тут подробности:
http://mobcode.com/2006/12/22/charting-ruby-class-and-metacl.

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

В языках типа С++, джавы и шарпа так сложилось исторически — есть примитивные заранее определенные типы, и есть более сложные сущности — классы.

Untrue в отношении шарпа (и, практически наверняка, жавы).
typeof(int) == typeof(System.Int32)
Это просто алиас.
При этом System.Int32 есть структура, состоящая ровно из четырёх байтов и являющаяся сишным четырёхбайтным интом for all conceivable purposes. К этой структуре приписаны методы, как статические, так и instance. Static typing в сочетании с правилом structures are sealed (final) (в шарпе есть специальное словосочетание: value type) позволяет реализовать это без дополнительных затрат памяти на classId.
В жаве долгое время не было автоматического боксинга/анбоксинга, поэтому использовались два разных объявления, просто int, который попадал на стек (при объявлении локальной переменной) или непосредственно в структуру encapsulating class (при объявлении члена и другое, боюсь неправильно написать, которое описывало указатель на класс, содержащий инт. В шарпе как-то без этого обошлись, причём забавно, бокснутые инты в принципе существовали, а описывающий их тип появился только во второй версии.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *