Г. Шилдт - С#4.0 Полное руководство (1160795), страница 28
Текст из файла (страница 28)
объект. член В этой форме объект указывается слева, а член — справа. Например, присваивание значения 2 переменной Р1оогз объекта Ьопзе осуществляется с помощью следующего оператора. почве.Р1оогз = 2; В целом, оператор-точка служит для доступа к переменным экземпляра и методам. Ниже приведен полноценный пример программы, в которой используется класс Вп11с(1по. Программа, в которой используется класс Во1101пЧ. ивтпо Бувтеьп с1азв Ви1101ЬЧ ( рпЬ11с тпт Р1оогв; // количество этажей рпЬ11с 1пб Игеа; l! общая площадь здания рчЬ11с 1пс Оссчрапгв; // количество жильпсв ) В этом классе объявляется объект типа Впь1С1по. с1азв Вв1101пчоещо ( всастс чотб мага() ( Внь1С1пч почве = пен Вп11сьпч()) // создать объект типа Вп11бьпч тпс агеаРР; // плошадь на одного человека // Присвоить значения полям в объекте Ьопве.
почве.осснрапгв = 4) почве.агеа = 2500) Ьопве.Р1оогв = 2; Вычислить площадь на одного человека. агеаРР = почве.))геа ! Ьонзе.осспраптв; Глава 6. Введение в классы,объекты и методы 151 Сопяо1е. Ига геъьпе ("Дом имеет: 1п Почве.Р1оогя + " этажаьп Почве.бссцрапгя + " жильцаьп Почве.ягеа + кв.
футов общей площади, иэ нихзп агеарр + " приходится на одного человека") Эта программа состоит из двух классов; Вц11г)1пд и В011с)1пдРещо. В классе Вц11с)1поРещо сначала создается экземпляр Лоцяе класса Вц11г)1пд с помощью метода Мадп ( ), а затем в коде метода Маьп () осуществляется доступ к переменным экземпляра Ьоцяе для присваивания им значений и последующего использования этих значений. Следует особо подчеркнуть, что Вц11г)1пц и Вц11с(1поРещо — это два совершенно отдельных класса. Единственная взаимосвязь между ними состоит в том, что в одном из них создается экземпляр другого.
Но, несмотря на то, что это раздельные классы, у кода из класса Вц11с)ьпопещо имеется доступ к членам класса Ви11с фпо, поскольку они объявлены как открытые (рцЬ11с). Если бы при их объявлении не был указан спецификатор доступа рцЬ11с, то доступ к ним ограничивался бы пределами Вц11с)1пд, а следовательно, их нельзя было бы использовать в классе Вц11с)1пдРещо.
Допустим, что исходный текст приведенной выше программы сохранен в файле Ряенц11б1пд. ся. В результате ее компиляции создается файл Ряенц11с)1по. ехе. При этом оба класса, Вц11с)1по и Вц11с)1порещо, автоматически включаются в состав исполняемого файла. При выполнении данной программы выводится следующий результат. Дом имеет: 2 этажа 4 жильца 2500 кв. футов общей площади, иэ них 525 приходится на одного человека Но классам Вц11с(1по и Вц11б1пдрещо совсем не обязательно находиться в одном и том же исходном файле. Каждый из них можно поместить в отдельный файл, например Вц11г)1пд. ся и Вп11с(1прРещо.
ся, а компилятору С() достаточно сообщить, что оба файла должны быть скомпилированы вместе. Так, если разделить рассматриваемую здесь программу на два таких файла, для ее компилирования можно воспользоваться следующей командной строкой. сво Вчьзозпд.се Вч11азпспещо.св Если вы пользуетесь интегрированной средой разработки у'(яца) Яцг(10, то вам нужно ввести оба упомянутых выше файла в свой проект и затем скомпоновать их.
Прехсде чем двигаться дальше, рассмотрим следующий основополагающий принцип: у каждого объекта имеются свои. копии переменных экземпляра, определенных в его классе. Следовательно, содержимое переменных в одном объекте может отличаться от их содержимого в другом объекте. Между обоими объектами не существует никакой связи, за исключением того факта, что они являются объектами одного и того же типа. Так, если имеются два объекта типа Вц11с(1по, то у каждого из них своя копия переменных Р1оогя, Агеа и Оссцрапся, а их содержимое в обоих объектах может отличаться.
Этот факт демонстрируется в следующей программе. 152 Часть 1. Язык С№ // В этой программе создаются два объекта типа Вцг1бгпо. ця1пд Вуясещг с1аяя Вц11б1пс ( рцЬ11с РпС Р1оогя; О количество этажей рцЬ11с гпг Агеат // общая площадь здания рцЬ11с 1пС Оссораптя; // количество жильцов ) // В этом классе объявляются два объекта типа Вц11бгпс. с1аяя Вц11бгпсоещо ( яоаС1с чогб Мати() ( Вц11бгпс Ьоцве = лен Вцг161пс()Г Вц11№ьпд огттсе = пеи Вцг1№ьпд()г гпС агеаррг // площадь на одного человека Присвоить значения полям в объекте Ьоцяе. Ьоияе.оссорапся = 44 Ьоцяе.Агеа = 2500; Ьоцяе.Р1оогя = 2; Присвоить значения полям в объекте огг1се. оттгсе.оссцрапся = 254 огг1се.дгеа = 42004 оттгсе.Р1оогя = 3; // Вычислить площадь на одного человека в жилом доме.
агеаРР = Ьоцяе.Агеа / Ьоцяе.оссцрапгя; Сопяо1е.игспесгпе("Дом имеет:тп Ьоцяе.Р1оогя + " этажатп ьоцяе.оссцрапся 4 " жильца1п Ьоцяе.ягеа + кв. футов общей площади, из них1п агеаРР + " приходится на одного человека" ) Вычислить площадь на одного человека в учреждении. агеаРР = оттгсе.йгеа / оттгсе.оссцрацСяг Сопяо1е.игтгеььпе("Учреждение имеет:1п огггсе.Р1оогя + " этажатп отььсе.оссцрапгя т " работниковтп оттгсе.Агеа + кв.
фУтов общей площади, из нихтп агеаРР + " приходится на одного человека"); Ниже приведен результат выполнения этой программы. Дом имеет: 2 этажа 4 жильца 2500 кв. футов общей площади, иэ них 625 приходится на одного человека Глава 6. Введение в классы,объеюы и методы 153 Учреждение имеет: 3 этажа 25 работников 4200 кв.
футов обшей площади, иэ них 1бв приходится на одного человека Как видите, данные из объекта поп ее полностью отделены от данных, содержащихся в объекте осйсе. Эта ситуация наглядно показана на рис. 6.1. е * Рис. 6.1. Переменные экземпляра одного объекта полностью отделены от переменных экземпляра другого объекта Создание объектов В предыдущих примерах программ для объявления объекта типа Вп11П1пд использовалась следующая строка кода.
Ви11итпч 'понэе = пен Вн11бтпо П Эта строка объявления выполняет три функции. Во-первых, объявляется переменная попэе, относящаяся к типу класса В011бзпо. Сама эта переменная не является объектом, а лишь переменной, которая может ссылаться на объект. Во-вторых, создается конкретная, физическая, копия объекта.
Зго делается с помощью оператора пеи. И наконец, переменной посэе присваивается ссылка на данный объект. Таким образом, после выполнения анализируемой строки объявленная переменная Ьопэе ссылается на объект типа Вн11441пд. Оператор пеы динамически (т.е, во время выполнения) распределяет память для объекта и возвращает ссылку на него, которая затем сохраняется в переменной.
Следовательно, в СФ для объектов всех классов должна быть динамически распределена память. Как и следовало ожидать, объявление переменной поп ее можно отделить от создания объекта, на который она ссылается, следующим образом. Вн1101пч 11оиве; // объявить ссылку на объект Лопве = пен Вп11б1пв П; // распределить память для объекта типа Вп11бспд В первой строке объявляется переменная попэе в виде ссылки на объект типа Вп11б1пгг. Следовательно, попе е — это переменная, которая может ссылаться на объект, хотя сама она не является объектом.
А во второй строке создается новый объект типа Впь1бспп, и ссылка на него присваивается переменной понэе. В итоге переменная посв е оказывается связанной с данным объектом. 154 Часть!. Язык С() То обстоятельство, что объекты классов доступны по ссылке, объясняет, почему классы называются ссылая ными и)лиями. Главное отличие типов значений от ссылочных типов заключается в том, что именно содержит переменнал каждого из этих типов. Так, переменная типа значения содержит конкретное значение. Например, во фрагменте кода 1пг х; х = 10; переменная х содержит значение 10, поскольку она относится к типу 1 0г, который является типом значения.
Но в строке Впг1г(гпэ )гопае = пеи Вп110гпэ()) переменная )топзе содержит не сам объект, а лишь ссылку на него. Переменные ссылочного типа и присваивание В операции присваивания переменные ссылочного типа действуют иначе, чем переменные типа значения, например типа 1пг. Когда одна переменнал типа значения присваивается другой, ситуация оказывается довольно простой. Переменнал, находящался в левой части оператора присваивания, получает копию значения переменной, находящейся в правой части этого оператора. Когда же одна переменная ссылки на объект присваивается другой, то ситуация несколько усложняется, поскольку такое присваивание приводит к тому, что переменная, находящаяся в левой части оператора присваивания, ссылается на тот же самый объект, на который ссылается переменная, находящаяся в правой части этого оператора. Сам же объект не копируется.
В силу этого отличия присваивание переменных ссылочного типа может привести к несколько неожиданным результатам. В качестве примера рассмотрим следующий фрагмент кода. В01101пэ Ьапае1 = пеи Вп11дгпэ(); Вп11г(гпэ )1опае2 = Ьапае1) На первый взгляд, переменные ))опзе1 и Попае2 ссылаются на совершенно разные объекты, но на самом деле это не так. Переменные ))опзе1 и )аопае2, напротив, ссылаются на один и тот же объект. Когда переменная попае1 присваивается переменой ))опзе2, то в конечном итоге переменная ))опае2 просто ссылается на тот же самый объект, что и переменная ))оп ае1. Следовательно, этим объектом можно оперировать с помощью переменной ))опзе1 или )аопае2. Например, после очередного присваиванил Аапае1.Агеа = 2600; оба метода э)г1ге11пе () Сопао1е.нггпесгпе(Лопае1.Агеа) Сопао1е.иггсеъгпе(ьеаае2.Агеа) выводят одно и то же значение: 2600.
Несмотря на то что обе переменные, )а оп а е1 и Попа е2, ссылаются на один и тот же объект, они никак иначе не связаны друг с другом. Например, в результате следующей последовательности операций присваивания просто изменяется объект, на который ссылается переменная )гопзе2. Глава 6. Введение в классы,объекты и методы 155 Вн11бгпэ Вш1бъпэ Вн11с(1пэ Поняе2 Поняе1 = пен Вн11б1пэ(); Поняе2 = Поняе1; Поояез = пен Вн11бьпд (): Поняез; 22 теперь обе переменные, Поняе2 и Поняез, ссылаются на один и тот ке объект. Методы Как пояснллось выше, переменные экземпляра и методы являются двумя основными составляющими классов. До сих пор класс Во11г(1пп, рассматриваемый здесь в качествв примера, содержал только данные, но не методы.
Хотя классы, содержащие только данные, вполне допустимы, у большинства классов должны быль также методы. Методы представляют собой подпрограммы, которые манипулируют данными, определенными в классе, а во многих случаях они предоставляют доступ к этим данным. Как правило, другие части программы взаимодействуют с классом посредством его методов. Метод состоит из одного или нескольких операторов. В грамотно написанном коде СФ каждый метод выполняет только одну функцию. У каждого метода имеется свое имя, по которому он вызывается. В общем, методу в качестве имени можно присвоить любой действительный идентификатор. Следует, однако, иметь в виду, что идентификатор Ма1п () зарезервирован для метода, с которого начинается выполнение программы.