C# 4.0 полное руководство - 2011
Шрифт:
3 этажа 25 работников
4200 кв. фу^ов общей площади, из них 168 приходится на одного человека
Как видите, данные из объекта house полностью отделены от данных, содержащихся в объекте office. Эта ситуация наглядно показана на рис. 6.1.
Рис. 6.1. Переменные экземпляра одного объекта полностью отделены от переменных экземпляра другого объекта
Создание объектов
В предыдущих
Building house = new Building;
Эта строка объявления выполняет три функции. Во-первых, объявляется переменная house, относящаяся к типу класса Building. Сама эта переменная не является объектом, а лишь переменной, которая может ссылаться на объект. Во-вторых, создается конкретная, физическая, копия объекта. Это делается с помощью оператора new. И наконец, переменной house присваивается ссылка на данный объект. Таким образом, после выполнения анализируемой строки объявленная переменная house ссылается на объект типа Building.
Оператор new динамически (т.е. во время выполнения) распределяет память для объекта и возвращает ссылку на него, которая затем сохраняется в переменной. Следовательно, в C# для объектов всех классов должна быть динамически распределена память.
Как и следовало ожидать, объявление переменной house можно отделить от создания объекта, на который она ссылается, следующим образом.
Building house; // объявить ссылку на объект
house = new Building; // распределить память для объекта типа Building
В первой строке объявляется переменная house в виде ссылки на объект типа Building. Следовательно, house — это переменная, которая может ссылаться на объект, хотя сама она не является объектом. А во второй строке создается новый объект типа Building, и ссылка на него присваивается переменной house. В итоге переменная house оказывается связанной с данным объектом.
То обстоятельство, что объекты классов доступны по ссылке, объясняет, почему классы называются ссылочными типами. Главное отличие типов значений от ссылочных типов заключается в том, что именно содержит переменная каждого из этих типов. Так, переменная типа значения содержит конкретное значение. Например, во фрагменте кода
int х; х = 10;
переменная х содержит значение 10, поскольку она относится к типу int, который является типом значения. Но в строке
Building house = new Building;
переменная house содержит не сам объект, а лишь ссылку на него.
Переменные ссылочного типа и присваивание
В операции присваивания переменные ссылочного типа действуют иначе, чем переменные типа значения, например типа int. Когда одна переменная типа значения присваивается другой, ситуация оказывается
Building housel = new Building;
Building house2 = housel;
На первый взгляд, переменные housel и house2 ссылаются на совершенно разные объекты, но на самом деле это не так. Переменные housel и house2, напротив, ссылаются на один и тот же объект. Когда переменная housel присваивается переменой house2, то в конечном итоге переменная house2 просто ссылается на тот же самый объект, что и переменная housel. Следовательно, этим объектом можно оперировать с помощью переменной housel или house2. Например, после очередного присваивания
housel.Area = 2600; оба метода WriteLine
Console.WriteLine(housel.Area);
Console.WriteLine(house2.Area);
выводят одно и то же значение: 2600.
Несмотря на то что обе переменные, housel и house2, ссылаются на один и тот же объект, они никак иначе не связаны друг с другом. Например, в результате следующей последовательности операций присваивания просто изменяется объект, на который ссылается переменная house2.
Building housel = new Building;
Building house2 = housel;
Building house3 = new Building;
house2 = house3; // теперь обе переменные, house2 и house3,
// ссылаются на один и тот же объект.
После выполнения этой последовательности операций присваивания переменная house2 ссылается на тот же самый объект, что и переменная house3. А ссылка на объект в переменной housel не меняется.
Методы
Как пояснялось выше, переменные экземпляра и методы являются двумя основными составляющими классов. До сих пор класс Building, рассматриваемый здесь в качестве примера, содержал только данные, но не методы. Хотя классы, содержащие только данные, вполне допустимы, у большинства классов должны быть также методы. Методы представляют собой подпрограммы, которые манипулируют данными, определенными в классе, а во многих случаях они предоставляют доступ к этим данным. Как правило, другие части программы взаимодействуют с классом посредством его методов.