Тип объекта (объектно-ориентированное программирование) - Википедия - Object type (object-oriented programming)
Эта статья поднимает множество проблем. Пожалуйста помоги Улучши это или обсудите эти вопросы на страница обсуждения. (Узнайте, как и когда удалить эти сообщения-шаблоны) (Узнайте, как и когда удалить этот шаблон сообщения)
|
В Информатика, тип объекта (a.k.a. объект упаковки) это тип данных что используется в объектно-ориентированного программирования к сворачивать не объектный тип, чтобы он выглядел как динамичный объект.[нужна цитата ]
Немного объектно-ориентированные языки программирования проводить различие между ссылка и типы значений, часто называемые объектами и не-объектами на платформах, где не существуют сложные типы значений, по таким причинам, как эффективность времени выполнения и синтаксические или семантические проблемы. Например, Ява имеет примитивные классы-оболочки соответствует каждому примитивный тип: Целое число
и int
, Характер
и char
, Плавать
и плавать
и т. д. Такие языки, как C ++ мало или совсем не имею представления о ссылочный тип; таким образом, использование типа объекта не представляет особого интереса.
Заниматься боксом
Упаковка, также известная как упаковка, - это процесс помещения примитивного типа в объект, чтобы этот примитив можно было использовать в качестве ссылочного объекта. Например, в Java LinkedList
может изменять свой размер, но массив должен иметь фиксированный размер. Кто-то может пожелать иметь LinkedList
из int
, но LinkedList
class перечисляет только ссылки на динамические объекты - он не может перечислять примитивные типы, которые являются типами значений.
Чтобы обойти это, int
может быть помещен в Целое число
, которые являются динамическими объектами, а затем добавляются в LinkedList
из Целое число
. (С помощью общий параметризованные типы, представленные в J2SE 5.0 этот тип представлен как LinkedList<Целое число>
.)С другой стороны, C # не имеет примитивных классов-оболочек, но допускает упаковку любого типа значения, возвращая общий Объект
ссылка. В Цель-C, любое примитивное значение может иметь префикс @
} чтобы сделать NSNumber
из него (например, @123
или же @(123)
). Это позволяет добавлять их в любую из стандартных коллекций, например в NSArray
.
Упакованный объект всегда является копией объекта значения и обычно неизменный. Распаковка объекта также возвращает копию сохраненного значения. Повторная упаковка и распаковка объектов может серьезно сказаться на производительности, потому что упаковка динамически распределяет новые объекты и распаковка (если значение в штучной упаковке больше не используется) делает их подходящими для вывоз мусора. Однако современные сборщики мусора, такие как сборщик мусора Java HotSpot по умолчанию, могут более эффективно собирать недолговечные объекты, поэтому, если упакованные объекты недолговечны, влияние на производительность может быть не таким уж плохим.
В некоторых языках существует прямая эквивалентность между распакованным примитивным типом и ссылкой на неизменяемый упакованный тип объекта. Фактически, можно заменить все примитивные типы в программе упакованными типами объектов. В то время как присвоение одного примитива другому будет копировать его значение, присвоение одной ссылки помещенному в коробку объекту другому скопирует значение ссылки для ссылки на тот же объект, что и первая ссылка. Однако это не вызовет никаких проблем, потому что объекты неизменяемы, поэтому семантически нет реальной разницы между двумя ссылками на один и тот же объект или на разные объекты (если вы не смотрите на физическое равенство). Для всех операций, кроме присваивания, таких как арифметика, сравнение и логические операторы, можно распаковать упакованный тип, выполнить операцию и повторно упаковать результат по мере необходимости. Таким образом, можно вообще не хранить примитивные типы.
Автобокс
Автобоксинг - это термин для получения ссылочного типа из типа значения только через преобразование типов (неявный или явный). Компилятор автоматически предоставляет дополнительный исходный код, который создает объект.
Например, в версиях Java до J2SE 5.0 следующий код не компилировался:
Целое число я = новый Целое число(9);Целое число я = 9; // ошибка в версиях до 5.0!
Компиляторы до 5.0 не принимали последнюю строку. Целое число
являются эталонными объектами, на поверхности не отличными от Список
, Объект
, и так далее. Чтобы преобразовать из int
для Целое число
, нужно было «вручную» создать экземпляр объекта Integer. Начиная с J2SE 5.0, компилятор примет последнюю строку и автоматически преобразует ее так, чтобы для хранения значения был создан объект Integer. 9
.[1] Это означает, что, начиная с J2SE 5.0, что-то вроде Целое число c = а + б
, куда а
и б
находятся Целое число
сами, теперь будут компилироваться - a и b распакованы, целочисленные значения суммируются, а результат автоматически упаковывается в новый Целое число
, который, наконец, сохраняется внутри переменной c
. Операторы равенства нельзя использовать таким образом, потому что операторы равенства уже определены для ссылочных типов, для равенства ссылок; чтобы проверить равенство значений в типе в штучной упаковке, нужно вручную распаковать их и сравнить примитивы или использовать Объекты.равно
метод.
Другой пример: J2SE 5.0 позволяет программисту обрабатывать коллекцию (например, LinkedList
), как если бы он содержал int
значения вместо Целое число
объекты. Это не противоречит тому, что было сказано выше: коллекция по-прежнему содержит только ссылки на динамические объекты и не может перечислять примитивные типы. Это не может быть LinkedList<int>
, но это должно быть LinkedList<Целое число>
вместо. Однако компилятор автоматически преобразует код так, что список будет «незаметно» получать объекты, в то время как исходный код упоминает только примитивные значения. Например, теперь программист может написать список.Добавить(3)
и думать, как будто int
3
добавлены в список; но компилятор фактически преобразовал строку в список.Добавить(новый Целое число(3))
.
Распаковка
Распаковка относится к получению значения, связанного с данным объектом, просто посредством преобразования типа (неявного или явного). Компилятор автоматически предоставляет дополнительный исходный код, который извлекает значение из этого объекта, либо вызывая какой-либо метод для этого объекта, либо другими способами.
Например, в версиях Java до J2SE 5.0 следующий код не компилировался:
Целое число k = новый Целое число(4);int л = k.intValue(); // всегда в порядкеint м = k; // было бы ошибкой, но теперь ладно
C # не поддерживает автоматическую распаковку в том же смысле, что и Java, потому что у него нет отдельного набора примитивных типов и типов объектов. Все типы, которые в Java имеют как примитивную, так и объектную версию, автоматически реализуются компилятором C # как либо примитивные (значения), либо как объектные (ссылочные) типы.
На обоих языках автоматическая установка бокса не выполняется автоматически, т.е. следующий код не компилируется:
C #:
int я = 42;объект о = я; // коробкаint j = о; // распаковка (ошибка)Консоль.WriteLine(j); // недостижимая строка, автор мог ожидать вывода "42"
Ява:
int я = 42;Объект о = я; // коробкаint j = о; // распаковка (ошибка)Система.из.println(j); // недостижимая строка, автор мог ожидать вывода "42"
Помощники типов
В Modern Object Pascal есть еще один способ выполнять операции с простыми типами, близкие к боксу, называемые помощниками типов в FreePascal или запишите помощников в Delphi и FreePascal в режиме Delphi.
Упомянутые диалекты являются языками компиляции Object Pascal для нативных языков, поэтому в них отсутствуют некоторые функции, которые могут реализовать C # и Java. В частности, вывод типа во время выполнения для строго типизированных переменных.
Но особенность связана с боксом.
Это позволяет программисту использовать такие конструкции, как
{$ ifdef fpc} {$ mode delphi} {$ endif}использует sysutils; // этот блок содержит обертки для простых типоввар Икс:целое число=100; s:нить;начинать s:= Икс.Нанизывать; Writeln(s);конец.