ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.12.2025

Просмотров: 3247

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

объект, все ссылки на который утрачены. Дополнительные сведения о сборке мусора бу-1 дут приведены в конце главы 12, "Наследование".

К л а с с ы , с о д е р ж а щ и е к л а с с ы

Члены класса могут, в свою очередь, быть ссылками на другие классы. Например! транспортное средство имеет двигатель, свойствами которого являются, в частности! мощность и рабочий объем. Можно поместить эти параметры непосредственно в клася V e h i c l e следующим образом:

p u b l i c c l a s s V e h i c l e

{

 

 

p u b l i c

s t r i n g sModel;

p u b l i c

s t r i n g sManufacturer ;

p u b l i c

i n t

nNumOfDoors;

p u b l i c

i n t

nNumOfWheels;

p u b l i c

i n t

nPower;

p u b l i c

doubl e d i s p l a c e m e n t ;

}

//Модель

//Производитель

//Количество дверей

//Количество колес

//Мощность двигателя

//Рабочий объем

Однако мощность и рабочий объем двигателя не являются свойствами автомобиля,! так как, например, джип моего сына может поставляться с одним из двух двигателей! с совершенно разными мощностями.

Двигатель является самодостаточной концепцией и может быть описан отдельным! классом:

p u b l i c c l a s s Motor

 

 

{

 

 

 

p u b l i c

i n t nPower;

//

Мощность

p u b l i c

doubl e d i s p l a c e m e n t ;

//

Рабочий объем

}

Вы можете внести этот класс в класс V e h i c l e следующим образом: p u b l i c c l a s s V e h i c l e

{

p u b l i c

s t r i n g sModel;

 

 

p u b l i c

s t r i n g sManufacturer ;

 

p u b l i c

i n t

nNumOfDoors;

 

p u b l i c

i n t

nNumOfWheels;

 

p u b l i c

Motor motor ;

}

/ / Модель / / Производитель

/ / Количество дверей / / Количество колес

Соответственно, создание s o n s C a r теперь выглядит так:

//Сначала создае м двигатель

Motor l a r g e r M o t o r

=

new M o t o r ( ) ;

largerMotor . nPowe r =

23 0;

l a r g e r M o t o r . d i s p l a c e m e n t = 4 . 0 ;

// Теперь создае м

автомобиль

V e h i c l e sonsCa r =

new V e h i c l e ( ) ;

sonsCar . sMode l =

"Cherokee S p o r t " ;

s o n s C a r . s M a n f a c t u r e r = " J e e p " ;

sonsCar.nNumOfDoors = 2;

sonsCar.nNumOfWheels

= 4;

//Присоединяем двигатель к автомобилю

sonsCar . moto r = l a r g e r M o t o r ;

122

Насть III. Объектно-основанное программирование


Доступ к рабочему объему двигателя из V e h i c l e можно получить в два этапа, как показано в приведенном фрагменте:

Motor m = sonsCar . motor ;

Console.WriteLine("Рабочий объем равен " + m . d i s p l a c e m e n t ) ; Однако можно получить эту величину и непосредственно:

Console.Writeline ("Рабочий объем равен " +

s o n s C a r . m o t o r . d i s p l a c e m e n t ) ;

Влюбом случае доступ к значению d i s p l a c e m e n t осуществляется через класс Motor.

Этот фрагмент взят из исходного текста программы VehicleAndMotor, которую можно найти на прилагаемом компакт-диске.

Статические ч л е н ы к л а с с а

Большинство членов-данных описывают отдельные объекты. Рассмотрим следующий

класс Саг:

 

 

public c l a s s Car

 

(

 

 

public

s t r i n g s L i c e n s e P l a t e ; // Номерной знак

автомобиля

I

 

 

Номерной

знак является свойством объекта, описывающим

каждый автомобиль

и уникальным для каждого автомобиля. Присваивание номерного знака одному автомо­

билю не меняет номерной знак другого:

Car cousinsCar = new Car () ;

cousinsCar. s L i c e n s e P l a t e

= "XYZ123";

Car yourCar = new Car () ;

 

yourCar. s L i c e n s e P l a t e =

"ABC789";

Однако имеются и такие свойства, которые присущи всем автомобилям. Например, количество выпущенных автомобилей является свойством класса Саг, но не отдельного объекта. Свойство класса помечается специальным ключевым словом s t a t i c , как пока­

зано в следующем фрагменте исходного текста:

 

public class Car

 

{

 

 

public

s t a t i c

 

int

nNumberOfCars; // Количество выпущенных

автомобилей

public

s t r i n g s L i c e n s e P l a t e ; // Номерной знак

автомобиля

}

Обращение к статическим членам выполняется не посредством объекта, а через сам класс, как показано в следующем фрагменте исходного текста:

// Создание нового объекта класса Саг

Car newCar = new Car () ; newCar.sLicensePlate = "ABC123";

// Увеличиваем количество автомобилей на 1

Car.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 .

Определение константных членов-данных

Одним специальным видом статических членов является член, представляющий бой константу. Значение такой константной переменной должно быть указано в объяви нии, и не может изменяться нигде в программе, как показано в следующем фрагмент исходного текста:

c l a s s P r o g r a m

{

/ / Ч и с л о д н е й в г о д у ( в к л ю ч а я в и с о к о с н ы й г о д )

p u b l i c

const i n t n D a y s I n Y e a r = 3 6 6 ;

p u b l i c

s t a t i c v o i d M a i n ( s t r i n g [ ] a r g s )

{

/ / Э т о м а с с и в — о н и х б у д е т р а с с к а з а н о н е м н о г о п о з ж е i n t [ ] n M a x T e m p e r a t u r e s = n e w i n t [ n D a y s I n Y e a r ] ;

f o r ( i n t i n d e x = 0 ; i n d e x < n D a y s I n Y e a r ; i n d e x + + )

{

/ / В ы ч и с л е н и е с р е д н е й т е м п е р а т у р ы д л я к а ж д о г о д н я г о д а

Константу n D a y s I n Y e a r можно использовать везде в вашей программе вместо ла 366. Константные переменные очень полезны, так как позволяют заме "магические числа" (в данном случае— 366) описательным именем n D a y s I n Y e a r , * повышает удобочитаемость программы и облегчает ее сопровождение.

С# имеет еще один способ объявления констант. Возможно, вам больше поим вится использовать не модификатор c o n s t , а модификатор r e a d o n l y :

p u b l i c readonly i n t n D a y s I n Y e a r = 3 6 6 ;

Как и при применении модификатора c o n s t , после того как вы присвоите конст инициализирующее значение, оно не может быть изменено нигде в программе. Xотя причины этого совета носят слишком технический характер, чтобы описывать их в стоящей книге, при объявлении констант предпочтительно использовать модификат r e a d o n l y .

Для констант имеется собственное соглашение по именованию. Вместо именован их так же, как и переменных (как в примере с n D a y s I n Y e a r ) многие программы предпочитают использовать прописные буквы с разделением слов подчеркиваниями DAYS_IN_YEAR. Такое соглашение ясно отделяет константы от обычных переменных.

В вашем распоряжении есть переменные, хранящие отдельные единственные значе ния. Классы могут использоваться для описания составных объектов. Но вам нужна еще

124

Часть III. Объектно-основанное программирова


одна конструкция для хранения множества объектов, например, коллекции старинных автомобилей Билла Гейтса. Встроенный класс A r r a y представляет собой структуру, ко­ торая может содержать последовательности однотипных элементов (чисел типа i n t , double, объекты V e h i c l e и т.п.).

Зачем нужны массивы

Рассмотрим задачу определения среднего из десяти чисел с плавающей точкой. Каж­ дое из 10 чисел требует собственной переменной для хранения значения типа d o u b l e (усреднение целых чисел может привести к ошибке округления, описанной в главе 3, "Объявление переменных-значений"):

double dO = 5; double dl = 2 ; double d2 = 7; double d3 = 3 . 5 ; double d4 = 6 . 5 ; double d5 = 8; double d6 = 1; double d7 = 9; double d8 = 1; double d9 = 3;

Теперь нужно просуммировать все эти значения и разделить полученную сумму на 10:

double dSum = dO

+ dl

+ d2 + d3 + d4 +

d5 + d6

+ d7 + d8 + d9;

double dAverage =

dSum / 10;

Перечислять все элементы — очень утомительно, даже если их всего 10. А теперь

представьте, что вам надо усреднить 10000 чисел...

Массив фиксированного размера

Ксчастью, вам не нужно отдельно именовать каждый из элементов. С# предоставляет

враспоряжение программиста массивы, которые могут хранить последовательности зна­ чений. Используя массив, вы можете переписать приведенный выше фрагмент следую­ щим образом:

double[] dArray = {5, 2, 7, 3 . 5 , 6 . 5 , 8, 1, 9, 1, 3} ;

Класс Array использует специальный синтаксис, который делает его более удобным в применении. Двойные квадратные скобки [] указывают на способ доступа к отдельным элементам массива:

dArray[0] соответствует dO dArray[1] соответствует dl

Нулевой элемент массива соответствует do, первый — dl и так далее.

Номера элементов массива — 0, 1, 2, ... — известны как их индексы.

(пава 6. Объединение данных

125

- классы и массивы

 


В С# индексы массивов начинаются с 0, а не с 1. Таким образом, элемент с индексом 1 не является первым элементом массива. Не забывайте об этом!

Использование d A r r a y было бы слабым улучшением, если бы в качестве индекса массива нельзя было использовать переменную. Применять цикл f o r существенно проще, чем записывать каждый элемент вручную, что и демонстрирует программа F i x e d A r r a y A v e r a g e .

11

' F i x e d A r r a y A v e r a g e

 

 

 

//

Усреднение

массива

чисел

фиксированного

р а з м е р а

с

/ / и с п о л ь з о в а н и е м ц и к л а

 

 

 

n a m e s p a c e

F i x e d A r r a y A v e r a g e

 

 

 

 

u s i n g

S y s t e m ;

 

 

 

 

 

p u b l i c

c l a s s

P r o g r a m

 

 

 

 

{

 

 

 

 

 

 

 

p u b l i c s t a t i c

v o i d M a i n ( s t r i n g [ ]

a r g s )

 

 

d o u b l e [ ]

d A r r a y =

 

 

 

{ 5 , 2 , 7 , 3 . 5 , 6 . 5 , 8 , 1 , 9 , 1 , 3 } ;

/ / Н а к о п л е н и е с у м м ы э л е м е н т о в / / м а с с и в а в п е р е м е н н о й d S u m d o u b l e d S u m = 0 ,-

f o r ( i n t i = 0 ; i < 1 0 ; i + + \

I

d S u m = d S u m + d A r r a y [ i ] ;

/ / В ы ч и с л е н и е с р е д н е г о з н а ч е н и я d o u b l e d A v e r a g e = d S u m / 1 0 ;

C o n s o l e . W r i t e L i n e ( d A v e r a g e ) ;

/ / О ж и д а е м п о д т в е р ж д е н и я п о л ь з о в а т е л я

C o n s o l e . W r i t e L i n e ( " Н а ж м и т е < E n t e r > д л я " +

" з а в е р ш е н и я п р о г р а м м ы . . . " ) ;

C o n s o l e . R e a d ( ) ;

Программа начинает работу с инициализации переменной d S u m значением 0. Затем программа циклически проходит по всем элементам массива d A r r a y и прибавляет га к dSum . По окончании цикла сумма всех элементов массива хранится в dSum . Раздели! ее на количество элементов массива, получаем искомое среднее значение.

Проверка границ массива

Программа F i x e d A r r a y A v e r a g e должна циклически проходить по массиву из 10 элементов. К счастью, цикл разработан так, что проходит ровно по 10 элементам мас­ сива. Ну а если была бы допущена ошибка и проход был бы сделан не по 10 элементам, а по иному их количеству? Следует рассмотреть два основных случая.

126

Часть III. Объектно-основанное программирование