ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 11.12.2025
Просмотров: 3270
Скачиваний: 1
Перегрузка функции
Ъ одном классе может быть две функции с одним и тем же именем — при условии различия их аргументов. Это явление называется перегрузкой
(overloading) имени функции.
Вот пример программы, демонстрирующей перегрузку.
//A v e r a g e A n d D i s p l a y O v e r l o a d e d - эта версия демонстрирует
//возможность перегрузки функции вычисления и вывода
//среднего значения
using S y s t e m ;
namespace A v e r a g e A n d D i s p l a y O v e r l o a d e d
{
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 )
{
// Вызов первой функции-члена
A v e r a g e A n d D i s p l a y ( " м о е й оценки", 3 . 5 ,
"твоей оценки",- 4 . 0 ) ;
C o n s o l e . W r i t e L i n e ( ) ;
// Вызов второй функции-члена
A v e r a g e A n d D i s p l a y ( 3 . 5 , |
4 . 0 ) ; |
// Ожидаем подтверждения |
пользователя |
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 ( ) ;
//A v e r a g e A n d D i s p l a y - вычисление среднего значения двух
//чисел и вывод его на экран с переданными функции
//метками этих чисел
p u b l i c s t a t i c |
|
|
|
v o i d A v e r a g e A n d D i s p l a y ( s t r i n g |
s i , d o u b l e |
d l , |
|
s t r i n g |
s 2 , d o u b l e |
d 2 ) |
|
{ |
|
|
|
double dAverage = (dl + d2) / 2 ; |
|
|
|
C o n s o l e . W r i t e L i n e ( " С р е д н е е " |
+ si |
|
|
+ ", равной " |
+ |
d l ) ; |
|
C o n s o l e . W r i t e L i n e ( " и " |
+ s2 |
|
|
+", равной " + d2
+", равно " + d A v e r a g e ) ;
}
public static void AverageAndDisplay(double dl,
d o u b l e d 2 )
{
d o u b l e d A v e r a g e = ( d l + d 2 ) / 2;
Глава 7. Функции функций |
153 |
C o n s o l e . W r i t e L i n e ( " с р е д н е е |
" |
+ d l |
+ " и " |
+ |
d 2 |
+ " р а в н о " |
|
+ d A v e r a g e ) ; |
В программе определены две версии функции A v e r a g e A n d D i s p l a y ( ) . Программ вызывает одну из них после другой, передавая им соответствующие аргументы. С# в col стоянии определить по переданным функции аргументам, какую из версий следует ви| звать, сравнивая типы передаваемых значений с определениями функций. Программ корректно компилируется и выполняется, выводя на экран следующие строки:
С р е д н е е |
м о е й о ц е н к и , р а в н о й 3 . 5 |
и т в о е й о ц е н к и , р а в н о й 4 , р а в н о 3 . 7 5 |
|
С р е д н е е |
3 . 5 и 4 р а в н о 3 . 7 5 |
Н а ж м и т е < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы . . .
Вообще говоря, С# не позволяет иметь в одной программе две функции с одинаковым! именами. В конце концов, как тогда он сможет разобраться, какую из функций следует вызш вать? Но дело в том, что С# в имя функции во внутреннем представлении компилятора вклш чает не только имя функции, но и количество и типы ее аргументов. Поэтому С# в состояв! отличить функцию A v e r a g e A n d D i s p l a y ( s t r i n g , d o u b l e , s t r i n g , d o u b l e ) отфуш ции A v e r a g e A n d D i s p l a y ( d o u b l e , d o u b l e ) . Если рассматривать эти функции с ихаи гументами, становится очевидным, что они разные.
Реализация аргументов по умолчанию
Зачастую оказывается желательно иметь две (или более) версии функции, имеюищ следующие отличия.
Одна из функций представляет собой более сложную версию, обеспечи вающую большую гибкость, но требующую большого количества аргу ментов от вызывающей программы, причем некоторые из них для пользо вателя могут быть просто непонятны.
Под пользователем функции зачастую подразумевается программист, пр меняющий ее в своих программах, так что пользователь функции и полк ватель готовой программы — это разные люди. Еще один термин, прим няемый для обозначения такого рода пользователя — клиент.
Вторая версия функции гораздо проще для применения, она работает же, как и первая, в которой часть аргументов принимает некоторые п допределенные значения по умолчанию.
Такое поведение легко реализуется с использованием перегрузки функций.
Рассмотрим следующую пару функций D i s p l a y R o u n d e d D e c i m a l ( ) :
/ / F u n c t i o n s W i t h D e f a u l t A r g u m e n t s - д в е в е р с и и о д н о й и т о й ж е
/ / |
ф у н к ц и и , п р и ч е м о д н а и з н и х п р е д с т а в л я е т в е р с и ю в т о р о й с |
/ / |
и с п о л ь з о в а н и е м з н а ч е н и й а р г у м е н т о в п о у м о л ч а н и ю |
154 |
Часть III. Объектно-основанное программирован® |
using S y s t e m ; |
|
|
|
namespace |
F u n c t i o n s W i t h D e f a u l t A r g u m e n t s |
|
|
( |
|
|
|
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 ) |
|
/ / В ы з о в ф у н к ц и и - ч л е н а |
|
||
C o n s o l e . W r i t e L i n e |
( " {0}1 1 , |
|
|
|
D i s p l a y R o u n d e d D e c i m a l ( 1 2 . 3 4 5 6 7 8 M , |
3 ) ) ; |
|
/ / О ж и д а е м п о д т в е р ж д е н и я п о л ь з о в а т е л я
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 i s p l a y R o u n d e d D e c i m a l - п р е о б р а з у е т з н а ч е н и е т и п а
/ / d e c i m a l в с т р о к у с о п р е д е л е н н ы м к о л и ч е с т в о м з н а ч а щ и х // цифр
p u b l i c s t a t i c
s t r i n g D i s p l a y R o u n d e d D e c i m a l ( d e c i m a l m V a l u e , i n t n N u m b e r O f S i g n i f i c a n t D i g i t s )
{
/ / С н а ч а л а о к р у г л я е м ч и с л о д о у к а з а н н о г о к о л и ч е с т в а / / з н а ч а щ и х ц и ф р
d e c i m a l m R o u n d e d V a l u e =
d e c i m a l . R o u n d ( m V a l u e ,
n N u m b e r O f S i g n i f i c a n t D i g i t s ) ; / / и п р е о б р а з у е м е г о в с т р о к у
s t r i n g s = C o n v e r t . T o S t r i n g ( m R o u n d e d V a l u e ) ;
r e t u r n s,-
}
p u b l i c s t a t i c
s t r i n g D i s p l a y R o u n d e d D e c i m a l ( d e c i m a l m V a l u e )
{
/ / |
В ы з ы в а е м D i s p l a y R o u n d e d D e c i m a l ( d e c i m a l , |
/ / |
у к а з а н и е м к о л и ч е с т в а з н а ч а щ и х ц и ф р п о |
s t r i n g s = D i s p l a y R o u n d e d D e c i m a l ( m V a l u e , r e t u r n s ;
i n t ) с у м о л ч а н и ю 2 ) ;
Функция D i s p l a y R o u n d e d D e c i m a l () преобразует значение типа d e c i m a l в зна чение типа s t r i n g с определенным количеством значащих цифр после десятичной точ ки. Поскольку числа типа d e c i m a l часто применяются в финансовых расчетах, наибо лее распространенными будут вызовы этой функции со вторым аргументом, равным 2. В анализируемой программе это предусмотрено, и вызов D i s p l a y R o u n d e d D e c i m a l () с одним аргументом округляет значение этого аргумента до двух ц и ф р после десятичной
'та 7. Функции функций |
155 |
точки, позволяя пользователю не беспокоиться о смысле и числовом значении второй аргумента функции.
Обратите внимание, что версия фунющи D i s p l a y R o u n d e d D e c i m a l ( d e c i m a l в действительности осуществляет вызов функции D i s p l a y R o u n d e d D e c i m a l ( d e c i m a l , i n t ) . Такая практика позволяет избежать ненужного дублировав кода. Обобщенная версия функции может использовать существенно большее количество аргументов, которые ее разработчик может даже не включить док| кументацию.
Аргументы по умолчанию не просто сберегают силы ленивого программна Программирование — работа, требующая высочайшей степени концентрат и излишние аргументы функции, для выяснения назначения и рекомендуем значений которых необходимо обращаться к документации, затрудняют про граммирование, приводят к перерасходу времени и повышают вероятное! внесения ошибок в код. Автор функции хорошо понимает взаимосвязи меж! аргументами функции и способен обеспечить несколько корректных перегру женных версий функции, более дружественных к клиенту.
Примечание для программистов на Visual Basic и C/C++: в С# единственный способ реализации аргументов по умолчанию — это перегрузка функций. С# не позволяет иметь необязательные аргументы.
Передача в функцию типов-значений
Базовые типы переменных, такие как i n t , d o u b l e , d e c i m a l , известны как тип значения. Переменные таких типов могут быть переданы в функцию одним из двух спо собов. По умолчанию эти переменные передаются в функцию по значению (by valuе альтернативная форма — передача по ссылке.
Программисты часто не совсем точны в употреблении терминов. Если речь идет ти пах-значениях, то когда программист говорит о "передаче переменной в функцию", это обычно означает "передача значения переменной в функцию".
Передача по значению
В отличие от ссылок на объекты, переменные с типами-значениями наподобие id или d o u b l e обычно передаются в функцию по значению, т.е. функции передается зна чение, содержащееся в этой переменной, но не сама переменная.
При такой передаче изменение значения соответствующей переменной внутри функции не вызовет изменения значения переданной переменной в вызывающей программе, что и демонстрируется следующей программой:
/ / |
P a s s B y V a l u e - п р о г р а м м а д л я д е м о н с т р а ц и и с е м а н т и к и |
/ / |
п е р е д а ч и а р г у м е н т а п о з н а ч е н и ю |
u s i n g S y s t e m ; |
|
n a m e s p a c e |
P a s s B y V a l u e |
{ |
|
p u b l i c |
c l a s s P r o g r a m |
{ |
|
156 |
Часть III. Объектно-основанное программировал |
/ / U p d a t e - ф у н к ц и я п ы т а е т с я м о д и ф и ц и р о в а т ь з н а ч е н и я |
|
/ / а р г у м е н т о в , п е р е д а н н ы е |
е й ; о б р а т и т е в н и м а н и е , ч т о |
/ / ф у н к ц и и в к л а с с е м о г у т |
б ы т ь о б ъ я в л е н ы в л ю б о м п о р я д к е |
p u b l i c |
s t a t i c v o i d U p d a t e ( i n t |
i , |
d o u b l e d ) |
||||||
{ |
i |
= 1 0 ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
d = 2 0 . 0 ; |
|
|
|
|
|
||||
} |
|
|
|
|
|
|
|
|
|
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 i |
= |
1 ; |
|
|
|
|
|
|
|
d o u b l e d = 2 . 0 ; |
|
|
|
|||||
|
C o n s o l e . W r i t e L i n e ( " П е р е д |
в ы з о в о м U p d a t e ( i n t , d o u b l e ) : " ) ; |
|||||||
|
C o n s o l e . W r i t e L i n e ( " i = " + i + ", d = " + d ) ; |
||||||||
|
/ / В ы з ы в а е м ф у н к ц и ю |
|
|
|
|||||
U p d a t e ( i , |
d ) ; |
|
|
|
|
||||
|
/ / О б р а т и т е в н и м а н и е — з н а ч е н и я 1 и 2 . 0 н е и з м е н и л и с ь |
||||||||
|
C o n s o l e . W r i t e L i n e ( " П о с л е в ы з о в а U p d a t e ( i n t , d o u b l e ) : " ) , - |
||||||||
|
C o n s o l e . W r i t e L i n e ( " i = " + i + ", d = " + d) ; |
||||||||
|
/ / О ж и д а е м п о д т в е р ж д е н и я п о л ь з о в а т е л я |
||||||||
|
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 ( ) ; |
|
|
|
|
||||
Выполнение программы дает такой вывод на экран: |
|||||||||
Перед |
в ы з о в о м |
U p d a t e |
( i n t , d o u b l e ) |
: |
|
||||
i = 1 , |
d |
= |
2 |
|
|
|
|
|
|
После |
в ы з о в а |
U p d a t e ( i n t , d o u b l e ) |
: |
|
|
||||
i = 1, |
d = |
2 |
|
|
|
|
|
|
|
Нажмите |
< E n t e r > |
д л я |
з а в е р ш е н и я |
п р о г р а м м ы . . . |
|||||
Вызов U p d a t e () передает функции значения 1 и 2.0, а не ссылки на переменные i и. Таким образом, изменение их значений в функции никак не влияет на значения исходных переменных в вызывающей программе.
Передача по с с ы л к е
Передача функции переменных с типами-значениями по ссылке имеет ряд преиму ществ — этот метод передачи используется, в частности, когда вызывающая программа хочет предоставить функции возможность изменять значение передаваемой в качестве аргумента переменной. Приведенная далее программа P a s s B y R e f e r e n c e демонстри рует эту возможность.
С# дает программисту возможность передачи аргументов по ссылке с ис пользованием ключевых слов r e f и o u t . Слегка измененная программа P a s s B y V a l u e демонстрирует, как это делается.
Глава 7. Функции функций |
157 |