ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 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. Объектно-основанное программирование |