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

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

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

Добавлен: 11.12.2025

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

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

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

мент объект l o c a l O b j e c t под курсором имеет значение n u l l . То же показы вает и окно Locals.

Рис. 11.2. Окно отладчика Visual Studio перед выполнением конструктора

5.Еще раз нажмите клавишу <F11>.

Программа перейдет к точке останова в конструкторе M y O t h e r O b j e c t , как! казано на рис. 11.3. Как мы сюда попали? Последний вызов в Main () приводит к запуску конструктора MyObj e c t . Однако перед началом выполнения конструк тора С# инициализирует статический член класса MyObject, который являет объектом типа M y O t h e r O b j e c t , так что инициализация подразумевает вызов его конструктора— где и находится точка останова (без нее нельзя было бы ос тановить здесь отладчик, хотя сам конструктор был бы выполнен — вы бы могли судить об этом по сообщению в окне консоли).

6.Дважды нажмите клавишу <F11>, после чего вы остановитесь на строке! статическим членом s t a t i c O b j , как показано на рис. 11.4.

Это означает, что конструктор этого объекта завершил свою работу.

7.Продолжайте нажимать клавишу <F11> для пошагового выполнения пр граммы.

При первом нажатии клавиши <F11> вы остановитесь в начале конструктора MyObject . Обратите внимание, что вы еще раз попадете в конструктор O t h e r O b j e c t , но на этот раз, когда конструктор MyObjec t будет создавать статический член d y n a m i c O b j .

250

Часть

IV.

Объектно-ориентированное

программирова

Puc. 11.3. Перед вызовом конструктора MyObject управление передается конструктору MyOtherObj ect

Puc. 11.4. После выполнения конструктора MyOtherObject вы возвра­ щаетесь в точку его вызова

Глава 11. Классы

251


Непосредственная инициализация объекта - конструктор по умолчанию

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

Итак, класс B a n k A c c o u n t можно записать следующим образом: p u b l i c c l a s s B a n k A c c o u n t

{

// Номера б а н к о в с к и х с ч е т о в н а ч и н а ю т с я с 1000 // н а з н а ч а ю т с я п о с л е д о в а т е л ь н о в в о з р а с т а ю щ е м s t a t i c i n t n N e x t A c c o u n t N u m b e r = 1 0 0 0 ;

// Для

к а ж д о г о с ч е т а п о д д е р ж и в а ю т с я е г о номер

i n t n A c c o u n t N u m b e r = + + n N e x t A c c o u n t N u m b e r ;

d o u b l e d B a l a n c e = 0 . 0 ;

I I . . .

п р о ч и е ч л е н ы . . .

и

по р я д к е

иб а л а н с

}

Вот в чем состоит работа инициализаторов. Как n A c c o u n t N u m b e r , так и dBalance получают значения как часть объявления, эффект которого аналогичен использованному указанного кода в конструкторе.

Надо очень четко представлять себе картину происходящего. Вы можете решить, что это выражение присваивает значение 0 . 0 переменной d B a l a n c e непосредственно. О ведь d B a l a n c e существует только как часть некоторого объекта. Таким образом, при сваивание не выполняется до тех пор, пока не будет создан объект BankAccount. Рас сматриваемое присваивание осуществляется всякий раз при создании объекта.

Заметим, что статический член-данные n N e x t A c c o u n t N u m b e r инициализируется при самом первом обращении к классу B a n k A c c o u n t (как вы убедились при выполнен нии демонстрационной программы в отладчике), т.е. обращении к любому свойству или методу объекта, владеющему статическим членом, в том числе и конструктору. Буду чи инициализирован, статический член повторно не инициализируется, сколько бы оби тов вы не создавали. Этим он отличается от нестатических членов.

Инициализаторы выполняются в порядке их появления в объявлении класса. Если () встречает и инициализаторы, и конструктор, то инициализаторы выполняются до выведе нения тела конструктора.

Конструирование с инициализаторами

Давайте в рассматривавшейся ранее программе D e m o n s t r a t e D e f a u l t C o n s t r u c t o r перенесем вызов new M y O t h e r O b j e c t () из конструктора M y O b j e c t в объявле ние так, как показано в приведенном далее фрагменте исходного текста полужирным шрифтом, и изменим второй вызов W r i t e L i n e ( ) .

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

{

/ /

Этот

ч л е н

я в л я е т с я

с в о й с т в о м

к л а с с а

s t a t i c

M y O t h e r O b j e c t

s t a t i c O b j

=

new M y O t h e r O b j e c t ( ) ;

/ /

Этот

ч л е н

я в л я е т с я

с в о й с т в о м

о б ъ е к т а

M y O t h e r O b j e c t d y n a m i c O b j = new

MyOtherObjectО;

p u b l i c

M y O b j e c t ( )

 

 

 

252

Часть

IV.

Объектно-ориентированное

программировав


Console . W r i t e L i n e ("Начало

к о н с т р у к т о р а

M y O b j e c t " ) ;

Console . WriteLine (" ( С т а т и ч е с к и е

члены "

+

" и н и ц и а л и з и р о в а н ы д о к о н с т р у к т о р а ) " ) ;

// Ранее з д е с ь с о з д а в а л с я

d y n a m i c O b j

 

Console . W r i t e L i n e ( " З а в е р ш е н и е

к о н с т р у к т о р а M y O b j e c t " ) ;

Сравните вывод на экран такой модифицированной программы с выводом на экран

•сходной программы

D e m o n s t r a t e D e f a u l t C o n s t r u c t o r .

Начало функции M a i n ( )

 

Создание локального о б ъ е к т а MyObjec t в

M a i n ( ) :

Конструирование

M y O t h e r O b j e c t

 

Конструирование M y O t h e r O b j e c t

 

Начало конструктора MyObjec t

 

(Статические члены и н и ц и а л и з и р о в а н ы до

к о н с т р у к т о р а )

Завершение к о н с т р у к т о р а MyObject

 

Н а ж м и т е < E n t e r > для з а в е р ш е н и я п р о г р а м м ы . . .

Полный текст данной программы можно найти на прилагаемом компактдиске в каталоге D e m o n s t r a t e C o n s t r u c t o r W i t h l n i t i a l i z e r .

Конструкторы можно перегружать так же, как и прочие методы.

Перегрузка функции обозначает определение двух функций с одним и тем же именем, но с разными типами аргументов (подробно этот вопрос рассматри­ вается в главе 7, "Функции функций").

Предположим, вы хотите обеспечить три способа создания объекта Bank - Account — с нулевым балансом, как и ранее, и два варианта с некоторыми начальными значениями.

B a n k A c c o u n t W i t h M u l t i p l e C o n s t r u c t o r s - б а н к о в с к и й с ч е т с разными вариантами конструкторов

Using System;

H o m e s p а с е B a n k A c c o u n t W i t h M u l t i p l e C o n s t r u c t o r s

Using System;

 

 

 

 

public class Program

 

 

 

 

{

 

 

 

 

public s t a t i c

v o i d

Main ( s t r i n g [ ]

a r g s )

{

 

 

 

 

// Создание

б а н к о в с к и х

с ч е т о в

с к о р р е к т н ы м и начальными

// значениями

 

 

 

BankAccount

b a l

= new

B a n k A c c o u n t ( ) ;

C o n s o l e . W r i t e L i n e ( b a l . G e t S t r i n g ( ) ) ;

Классы

253


B a n k A c c o u n t

Ьа2

=

new B a n k A c c o u n t ( 1 0 0 ) ;

C o n s o l e . W r i t e L i n e

(ba2 . G e t S t r i n g (.)).;

 

B a n k A c c o u n t

b a 3

=

new B a n k A c c o u n t ( 1 2 3

4 , 2 0 0 ) ;

C o n s o l e . W r i t e L i n e ( Ь а З . G e t S t r i n g ( ) ) ;

 

/ / Ожидаем

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

 

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 ( ) ;

//B a n k A c c o u n t

p u b l i c c l a s s

- простейший б а н к о в с к и й с ч е т B a n k A c c o u n t

{

//

Первый

номер с ч е т а

— 1 0 0 0 ;

номера с ч е т о в

 

/ / н а з н а ч а е т с я п о с л е д о в а т е л ь н о

 

 

 

 

s t a t i c i n t n N e x t A c c o u n t N u m b e r = 1 0 0 0 ;

 

 

//

Номер

с ч е т а и е г о

б а л а н с

 

 

 

 

 

i n t n A c c o u n t N u m b e r ;

 

 

 

 

 

 

d o u b l e d B a l a n c e ;

 

 

 

 

 

 

// Н е с к о л ь к о

к о н с т р у к т о р о в

- в

з а в и с и м о с т и

от

ваших

/ / п о т р е б н о с т е й

 

 

 

 

 

 

p u b l i c

B a n k A c c o u n t ( )

// А в т о м а т и ч е с к о г о к о н с т р у к т о р а нет

{

 

 

 

 

 

 

 

 

 

 

 

 

n A c c o u n t N u m b e r = + + n N e x t A c c o u n t N u m b e r ;

 

 

 

d B a l a n c e = 0 . 0 ;

 

 

 

 

 

 

}'

 

 

 

 

 

 

 

 

 

 

 

p u b l i c

B a n k A c c o u n t ( d o u b l e d l n i t i a l B a l a n c e )

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

/ /

П о в т о р е н и е ч а с т и

к о д а

и з к о н с т р у к т о р а

п о

умолчанию

 

n A c c o u n t N u m b e r = + + n N e x t A c c o u n t N u m b e r ;

 

 

 

//

Т е п е р ь —

к о д , специфичный

д ля

д а н н о г о

конструктора

 

//

Начинаем

с п е р е д а н н о г о

б а л а н с а

( е с л и

он

 

 

/ /

положительный)

 

 

 

 

 

 

 

if

( d l n i t i a l B a l a n c e < 0)

 

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

d l n i t i a l B a l a n c e = 0;

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

d B a l a n c e = d l n i t i a l B a l a n c e ;

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

p u b l i c B a n k A c c o u n t ( i n t n l n i t i a l A c c o u n t N u m b e r ,

 

 

 

 

 

 

d o u b l e d l n i t i a l B a l a n c e )

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

/ /

Игнорируем о т р и ц а т е л ь н ы й

номер

с ч е т а

 

 

 

if ( n l n i t i a l A c c o u n t N u m b e r <= 0)

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

254

Насть

IV.

Объектно-ориентированное программировал


n l n i t i a l A c c o u n t N u m b e r = + + n N e x t A c c o u n t N u m b e r ;

}

= n l n i t i a l A c c o u n t N u m b e r ;

nAccountNumber

// Начинаем с

п е р е д а н н о г о б а л а н с а ( е с л и он

//положительный)

if ( d l n i t i a l B a l a n c e < 0)

{

d l n i t i a l B a l a n c e = 0;

}

dBalance =

d l n i t i a l B a l a n c e ;

}

 

public s t r i n g

G e t S t r i n g ( )

{

r e t u r n S t r i n g . F o r m a t ( " # { 0 } = { l : N } " ,

n A c c o u n t N u m b e r , d B a l a n c e ) ;

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

В приведенной выше демонстрационной программе B a n k A c c o u n t W i t ^ h M u l t i - pleConstructors имеются три конструктора:

первый назначает номер счета и нулевой баланс;

второй назначает номер счета и инициализирует баланс переданным положитель­ ным значением (отрицательные значения игнорируются);

третий позволяет пользователю самостоятельно определить номер счета и поло­ жительный начальный баланс.

Функция Main () создает различные банковские счета с использованием каждого из ipex конструкторов и выводит информацию о созданных объектах. Вывод этой про­ чимы на экран имеет следующий вид:

#1001 = 0 . 0 0 #1002 = 1 0 0 . 00

# 1 2 3 4 = 2 0 0 0 0

Н а ж м и т е < E n t e r > дл я з а в е р ш е н и я п р о г р а м м ы . . .

В реальных классах требуется выполнять более строгую проверку входных па­ раметров конструктора, чтобы гарантировать их корректность.

Конструкторы различаются между собой по тем же правилам, что и перегруженные функции. Первый объект, конструируемый в функции Main ( ) , b a l , создается без аргументов, так что для него вызывается первый конструктор B a n k A c c o u n t ( ) , не получающий аргументов (он все еще именуется конструктором по умолчанию, хотя и не создается С# автоматически). Соответственно, этот счет получает номер по умолчанию и нулевой ба-

11. Классы

255