1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 22
Текст из файла (страница 22)
Это приводит к тому, что ввод пользователя находится на той nilстроке, что и приглашение. Кроме того, добавление символа новой стромГ' \ п ' создает пустую строку без необходимости вызывать W r i t e L i n e ( ) .О т л и ч и е м е ж д у объектамиЗаводы в Детройте в состоянии выпускать множество автомобилей и отслеживать кажду»|выпущенную машину и при этом не путать их. Аналогично, программа может создать несколько объектов одного и того же класса, как показано в следующем фрагменте:V e h i c l e c a r l = new V e h i c l e О ;carl.sManufacturer = "Studebaker";carl.sModel = "Avanti";/ / Следующий к о д никак н е в л и я е тV e h i c l e c a r 2 = new V e h i c l e ( ) ;c a r 2 . s M a n u f a c t u r e r = "Hudson";car2.sModel = "Hornet";наcarlСоздание объекта c a r 2 и присваивание ему имени и производителя никак не влияй]н а объект c a r l .Возможность различать объекты одного класса очень важна при программировании,Объект может быть создан, с ним могут быть выполнены различные действия — и онвсегда выступает как единый объект, отличный от других подобных ему объектов.СсылкиОператор "точка" и оператор присваивания — единственные два оператора, определенные для ссылочных типов.
Рассмотрим следующий фрагмент исходного текста:/ / С о з д а н и е н у л е в о й ссылкиV e h i c l e yourCar;// Присваивание значения ссылкеy o u r C a r = new V e h i c l e ( ) ;// И с п о л ь з о в а н и е точки для обращения к ч л е н уyourCar.sManufacturer = "Rambler";// Создание новой ссылки, к о т о р а я у к а з ы в а е т на тот жеV e h i c l e yourSpousalCar = yourCar;объектВ первой строке создается объект y o u r C a r , причем без присваивания ему значения,Такая неинициализированная ссылка называется нулевым объектом (null object). Любыепопытки использовать неинициализированную ссылку приводят к немедленной генерации ошибки, которая прекращает выполнение программы.Компилятор С# может перехватить большинство попыток использования неинициализированной ссылки и сгенерировать предупреждение в процессе компиляции программы. Если вам каким-то образом удалось провести компьютерто обращение к неинициализированной ссылке при выполнении программьприведет к ее аварийному останову.Второе выражение создает новый объект V e h i c l e и присваивает его ссылочной пе-1ременной y o u r C a r .
И последняя строка кода присваивает ссылке y o u r S p o u s a l C a r l120Часть III. Объектно-основанное программированиессылку y o u r C a r . Как показано на рис. 6.1, это приводит к тому, что y o u r S p o u s a l C a rссылается на тот же объект, что и y o u r C a r .Рис. 6.1. Взаимоотношения между двумя ссылками на один и тот же объектЭффект от следующих двух вызовов одинаков:// Создание вашей машиныVehicle y o u r C a r = new V e h i c l e () ;yourCar.
s M o d e l = " K a i s e r " ;// Эта машина п р и н а д л е ж и т и вашей ж е н еVehicle y o u r S p o u s a l C a r = y o u r C a r ;// Изменяя о д н у машину, вы и з м е н я е т е и д р у г у юyourSpousalCar. sModel = "Henry J " ;C o n s o l e . W r i t e L i n e ( " В а ш а машина - " + y o u r C a r . s M o d e l ) ;Выполнение данной программы приводит к выводу на экран названия моделиHenry J, а не K a i s e r .
Обратите внимание, что y o u r S p o u s a l C a r не указывает наyourCar— вместо этого просто и y o u r S p o u s a l C a r , и y o u r C a r указывают,на одини тот же объект.Кроме того, ссылка y o u r S p o u s a l C a r будет корректна, даже если окажется"потерянной" (например, при выходе за пределы области видимости), как показанов следующем фрагменте:// Создание вашей машиныVehicle y o u r C a r = new V e h i c l e () ;yourCar. s M o d e l = " K a i s e r " ;// Эта машина п р и н а д л е ж и т и вашей ж е н еVehicle y o u r S p o u s a l C a r = y o u r C a r ;// Когда о н а з а б и р а е т с е б е вашу м а ш и н у .
. .yourCar = n u l l ;// yourCar теперь ссылается на "нулевой// объект"// . . . y o u r S p o u s a l C a r с с ы л а е т с я на в с е ту же машинуC o n s o l e . W r i t e L i n e ( " В а ш а машина - " + y o u r S p o u s a l C a r . s M o d e l ) ;Выполнение этого фрагмента исходного текста выводит на экран сообщение"Ваша машина - K a i s e r " несмотря на то, что ссылка y o u r C a r стала недействительной.Объект перестал быть достижимым по ссылке y o u r C a r .
Но он не будет полностью недостижимым, пока не будут "потеряны" или обнулены обе ссылки —и yourCar, и y o u r S p o u s a l C a r .После этого — вернее будет сказать, в некоторый непредсказуемый момент послеэтого — сборщик мусора (garbage collector) С# вернет память, использованную ранее подГлава 6. Объединение данных - классы и массивы121объект, все ссылки на который утрачены. Дополнительные сведения о сборке мусора бу-1дут приведены в конце главы 12, "Наследование".Классы, содержащие классыЧлены класса могут, в свою очередь, быть ссылками на другие классы. Например!транспортное средство имеет двигатель, свойствами которого являются, в частности!мощность и рабочий объем.
Можно поместить эти параметры непосредственно в класяV e h i c l e следующим образом:public class Vehicle{// Модельp u b l i c s t r i n g sModel;publics t r i n g s M a n u f a c t u r e r ; // П р о и з в о д и т е л ь// К о л и ч е с т в о д в е р е йp u b l i c i n t nNumOfDoors;publici n t nNumOfWheels;// К о л и ч е с т в о к о л е сp u b l i c i n t nPower;// Мощность д в и г а т е л яpublic double displacement;// Р а б о ч и й о б ъ е м}Однако мощность и рабочий объем двигателя не являются свойствами автомобиля,!так как, например, джип моего сына может поставляться с одним из двух двигателей!с совершенно разными мощностями.Двигатель является самодостаточной концепцией и может быть описан отдельным!классом:publicclassMotor{publicpublici n t nPower;double displacement;/ / Мощность/ / Рабочий объем}Вы можете внести этот класс в класс V e h i c l e следующим образом:public{classpublicpublicpublicpublicpublic}Vehicles t r i n g sModel;s t r i n g sManufacturer;i n t nNumOfDoors;i n t nNumOfWheels;Motor motor;////////МодельПроизводительКоличество дверейКоличество колесСоответственно, создание s o n s C a r теперь выглядит так:/ / Сначала с о з д а е м д в и г а т е л ьM o t o r l a r g e r M o t o r = new M o t o r ( ) ;l a r g e r M o t o r .
n P o w e r = 23 0;largerMotor.displacement = 4.0;// Теперь с о з д а е м автомобильV e h i c l e s o n s C a r = new V e h i c l e ( ) ;sonsCar.sModel = "Cherokee S p o r t " ;sonsCar.sManfacturer = "Jeep";sonsCar.nNumOfDoors = 2;sonsCar.nNumOfWheels = 4;// Присоединяем д в и г а т е л ь к автомобилюsonsCar.motor = largerMotor;122Насть III. Объектно-основанное программированиеДоступ к рабочему объему двигателя из V e h i c l e можно получить в два этапа, какпоказано в приведенном фрагменте:Motor m = s o n s C a r .
m o t o r ;Console.WriteLine("Рабочий объем равен"+ m.displacement);Однако можно получить эту величину и непосредственно:Console.Writeline ("Рабочий объем равен " +sonsCar.motor.displacement);Влюбом случае доступ к значению d i s p l a c e m e n t осуществляется через класс M o t o r .Этот фрагмент взят из исходного текста программы V e h i c l e A n d M o t o r ,которую можно найти на прилагаемом компакт-диске.Статические ч л е н ы к л а с с аБольшинство членов-данных описывают отдельные объекты.
Рассмотрим следующийкласс Саг:public c l a s sCar(publicstringsLicensePlate;//НомернойзнакавтомобиляIНомерной знак является свойством объекта, описывающим каждый автомобильи уникальным для каждого автомобиля. Присваивание номерного знака одному автомобилю не меняет номерной знак другого:Car c o u s i n s C a r = new Car () ;cousinsCar. s L i c e n s e P l a t e = " X Y Z 1 2 3 " ;Car yourCar = new Car () ;yourCar. s L i c e n s e P l a t e = " A B C 7 8 9 " ;Однако имеются и такие свойства, которые присущи всем автомобилям.
Например,количество выпущенных автомобилей является свойством класса Саг, но не отдельногообъекта. Свойство класса помечается специальным ключевым словом s t a t i c , как показано в следующем фрагменте исходного текста:public class Car{public s t a t i cint nNumberOfCars; / / К о л и ч е с т в о выпущенных а в т о м о б и л е йpublic s t r i n g s L i c e n s e P l a t e ;/ / Номерной з н а к а в т о м о б и л я}Обращение к статическим членам выполняется не посредством объекта, а через самкласс, как показано в следующем фрагменте исходного текста:// Создание н о в о г о о б ъ е к т а к л а с с а СагCar newCar = new C a r () ;newCar.sLicensePlate = "ABC123";// Увеличиваем к о л и ч е с т в оа в т о м о б и л е й на1Car.nNumberOf Cars++ ;(пава 6. Объединение данных - классы и массивы123О б р а щ е н и е к ч л е н у о б ъ е к т а n e w C a r .
s L i c e n s e P l a t e в ы п о л н я е т с я посредством объекта n e w C a r , в то время как обращение к (статическому) членуC a r . n N u m b e r O f C a r s о с у щ е с т в л я е т с я с п о м о щ ь ю и м е н и к л а с с а . В с е объекттипа С а г совместно используют один и тот же член n N u m b e r O f C a r s .Определение константных членов-данныхО д н и м с п е ц и а л ь н ы м в и д о м с т а т и ч е с к и х ч л е н о в я в л я е т с я ч л е н , представляющийб о й к о н с т а н т у . З н а ч е н и е т а к о й к о н с т а н т н о й п е р е м е н н о й д о л ж н о б ы т ь у к а з а н о в объявинии, и не м о ж е т и з м е н я т ь с я нигде в п р о г р а м м е , к а к п о к а з а н о в с л е д у ю щ е м фрагментисходного текста:classProgram{//Числоpublicpublicднейвгодуi n tconsts t a t i c(включаяnDaysInYearvoidвисокосный=год)366;Main(string []args){//Этоint[]массив—онихбудетnMaxTemperaturesfor(intindex=0;=indexрассказаноnew<немногопозжеint[nDaysInYear];nDaysInYear;index++){//ВычислениесреднейтемпературыдлякаждогоднягодаКонстанту n D a y s I n Y e a r можно использовать везде в вашей программе вместола366.Константныепеременныеоченьполезны,таккакпозволяютзаме"магические числа" ( в данном с л у ч а е — 3 6 6 ) описательным именем n D a y s I n Y e a r , *повышает удобочитаемость программы и облегчает ее сопровождение.С# имеет еще один способ объявления констант.