@ince

Пользовательские типы и классы это примерно одно и тоже?

Пользовательские типы и классы это примерно одно и тоже?
Если нет, то чем отличаются?
  • Вопрос задан
  • 859 просмотров
Решения вопроса 3
@res2001
Developer, ex-admin
Класс является одним из вариантов пользовательских типов. Т.е. понятие пользовательский тип включает в себя не только классы, но и другие сущности (см. ответ Hemul GM )
Ответ написан
Комментировать
HemulGM
@HemulGM
Delphi Developer, сис. админ
Пользовательским тип может быть особым типом массива. TNumbers = array of Integer;
Перечисляемым типом. TNumbers = (nmOne, nmTwo, nmThree);
Структурой данных. TNumbers = record ID: integer; Name: string; end;
Ну и само-собой классом и прочим

Всё это зависит от конкретного языка. Так что спроси конкретнее.
Ответ написан
Комментировать
@majstar_Zubr
C++, C#, gamedev
Пользовательский тип в узком смысле это составной тип, реализующий некую абстракцию, у которой нет состояния.

Класс - просто одна из конструкций языка, которая позволяет выражать идеи в рамках парадигмы ООП.

В широком смысле, пользовательский тип - любой тип, который не определен в компиляторе / интерпретаторе и стандарте языка, а определен пользователем компилятора в исходном коде.

Разница вот в чем.

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

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

При переходе к ООП, структура неразрывно ассоциируется с некоторой функциональностью и некоторым состоянием. Здесь уже для своего пользовательского типа вручную необходимо описывать конструкцию и деструкцию типа. Некоторые языки второе реализуют через сборщик мусора, но в от в C# есть четкое различение между managed и unmanaged типами, потому что для вторых нужно писать финализатор - технически работающий как деструктор, но как подчеркивает наименование, он им не является, т.к. используется в рантайме сборщиком мусора.

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

Вкратце о вариантах трактовки пользовательского типа.

Первый вариант: синтаксический псевдоним. В C++ делается с помощью typedef, например size_t.

Второй вариант: Plain Data Object. В разных языках наименование варируется, но идея уходит корнями в структуру данных plain old data struct из Си, которая представляет просто участок памяти, в котором подряд идут публичные поля простых интегрированных типов. Например stuct plain_coord { int x; int y; }; Вот тут большая разница между классом, реализующим абстракцию "Координата" и POD: если вы в программе используете несколько систем координат, то класс, реализующий абстракцию, должен инкапсулировать все POD и конвертацию этих POD из одной системы координат в другую.

Третий вариант: указатели. Конкретно, в C++ в качестве пользовательских типов могут быть
указатели на функцию (пользователь хочет определить часть сигнатуры функции как тип)

указатели на функцию-член (более узкие требования, когда эта функция принадлежит какой-то иерархии)

указатели на составной тип (указатель на POD структуру, указатель на класс)

указатель на член класса

Четвёртый вариант: если язык поддерживает обобщённое программирование, то в качестве пользовательского типа можно использовать скаляр. Например, std:array имеет статический размер, определяемый на момент компиляции. std::array разных размеров суть разные типы. Хотя по факту, это разные классы, но это один шаблонный класс. Вот здесь как раз важнее представлять что-то как тип с некой функциональностью, а какой именно это класс не так важно, когда итак понятно, что это контейнер с определенным публичным интерфейсом.

Пятый вариант: наконец-то Object Reference класс. Но обычно, когда говорят о таких классах, их наоборот, категоризируют не как типы, а как реализации абстракций, потому что с течением времени задача уточняется, набор абстракции становится другим и приходится делать рефакторинг. Соответственно, может поменяться и набор классов, и предметная модель. А про типы тут даже и вспоминать нечего: они есть, они разные, вот и всё.

Остальные варианты: посмотрите в сторону Haskell, erlang. В целом, у разных языков разные требования к свойствам типов и предполагаемым методам использования типов. В основном это зависит от того, какую на какие парадигмы и на какую модель памяти нацелен язык программирования.

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

Войдите, чтобы написать ответ

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