Урок 1. Объект и экземпляры. Создание экземпляра по сильной и слабой ссылке


#1

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

Для того, что бы создать объект нужно написать:

new MyClass();

Вместо MyClass нужно подставлять тип объекта, экземпляр которого нужно создать.

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

  1. неуправляемая куча – область оперативной памяти, где ОС хранит свои данные, а также все активные приложения. Данные в неуправляемой куче не упорядочены: давно неиспользуемые данные нужно удалять вручную;
  2. управляемая куча – область памяти, которая находится внутри неуправляемой кучи, выделяется для приложений использующих .Net платформу. Данные в управляемой куче упорядочены, за управлением кучей отвечает отдельный механизм принадлежащий платформе .Net – сборщик мусора (Garbage Collector; GC).

Куча – это специальная область памяти, которая выделяется для каждого предложения использующего платформу .Net и в ней хранятся различные ссылочные данные (на эти данные ссылаются переменные в программном коде).

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

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

На самом деле пусть и было сказано, что используя эту запись мы создаём объект, но в ООП под объектом зачастую подразумевается нечто иное. Для разбора этого, давайте посмотрим изображение ниже:

При конструировании нашего объекта (самого первого для этого типа) в памяти он разбивается на две части:

  1. объект – это участок памяти, в котором хранится всё общее для всех «объектов» одного типа, а именно: описание их поведения (то есть методы) и некие статические члены (статика будет рассматриваться в дальнейшем).
  2. экземпляр – это участок памяти, в котором хранятся данные описывающие определённый «объект» данного типа, также в экземпляре храниться ссылка на объект (на своё поведение).

Примечание: на куче будет существовать только один объект для каждого класса, и все экземпляры этого класса будут ссылаться на него. Это сделано для экономии памяти (ОЗУ не бесконечна), а если бы объект создавался для каждого объекта отдельно, то в памяти было бы достаточно много повторяющееся информации (кол.экземпляров = кол. повторов), поскольку все экземпляры ведут себя одинаково.

Из этого следует, что на самом деле при использовании вот этой записи:

new MyClass();

мы не создавали объект, а создавали экземпляр класса MyClass.

Также нужно сказать о разнице между созданием экземпляра по слабой ссылке и по сильной ссылке:

  • когда экземпляр создаётся, и ссылка на него не записывается в переменную, тогда это создание экземпляра по слабой ссылке. Такое создание экземпляра можно использовать, если экземпляр нужен лишь для вызова определённого метода на нём и в дальнейшем не используется! Например: new MyClass().Method();
  • когда экземпляр создаётся, и ссылка на него записывается в переменную, тогда это создание экземпляра по сильной ссылке. Например:

MyClass instance = new MyClass();

Строку кода выше можно прочитать разными способами, вот 4 самые распространённые варианты:

  1. Создаем экземпляр класса MyClass (по сильной ссылке).
  2. Создаем экземпляр класса MyClass с именем instance.
  3. Инстанцируем класс MyClass.
  4. Создаем переменную с именем instance, типа MyClass и присваиваем ей адрес экземпляра на куче. (instance - является ссылкой на экземпляр класса MyClass построенный на куче)

Инстанцирование (instantiation) — создание экземпляра класса. В отличие от слова «создание», применяется не к объекту, а к классу. То есть, говорят: «создать экземпляр класса или инстанцировать класс».


Содержание справочника С# Essential