1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 59
Текст из файла (страница 59)
13.5.Puc.13.5.Разложение классов зависит от решаемой задачиГлава 13. Полиморфизм301Голая концепция, выражаемая абстрактным классомВернемся вочередной разк классу B a n k A c c o u n t .Б о л ь ш и н с т в о м е т о д о в э т о г о к л а с с а не в ы з ы в а ю т п р о б л е м , п о с к о л ь к у о б а типа банковских счетов о д и н а к о в о их реализуют. О д н а к о правила снятия со счета оказываютразличными, так что вы должны реализовать S a v e i n g s A c c o u n t . W i t h d r a w ()н е так,к а к C h e c k i n g A c c o u n t . W i t h d r a w ( ) . Н о к а к в ы п р е д п о л а г а е т е р е а л и з о в а т ь BankAccount.Withdraw()?Д а в а й т е о б р а т и м с я за п о м о щ ь ю к б а н к о в с к о м у с л у ж а щ е м у .
П р е д с т а в л я е т е э т о т диалог?— К а к о в ы правила снятия денег со счета? — с п р а ш и в а е т е вы.— С какого счета? Депозитного или чекового?— Со с ч е т а , — о т в е ч а е т е в ы . — П р о с т о со с ч е т а .П о л н о е непонимание в ответ.П р о б л е м а в т о м , ч т о з а д а н н ы й в о п р о с н е и м е е т н и к а к о г о с м ы с л а . Н е б ы в а е т такойв е щ и , к а к " п р о с т о с ч е т " . В с е с ч е т а ( в а н а л и з и р у е м о м п р и м е р е ) я в л я ю т с я л и б о депозитн ы м и , л и б о ч е к о в ы м и . К о н ц е п ц и я с ч е т а п р е д с т а в л я е т с о б о й а б с т р а к ц и ю , к о т о р а я объе д и н я е т о б щ и е с в о й с т в а к о н к р е т н ы х с ч е т о в .
О н а о к а з ы в а е т с я н е п о л н о й , п о с к о л ь к у в нейнедостает важного свойства W i t h d r a w ()( е с л и н е м н о г о п о р а з м ы ш л я т ь , т о найдутсяи другие отсутствующие свойства).Концепция B a n k A c c o u n t является абстракцией.Как использовать абстрактные классыАбстрактные классы используются для описания абстрактных концепций.Абстрактный класс — э т о к л а с с с о д н и м и л и н е с к о л ь к и м и а б с т р а к т н ы м и методами.Н а в е р н о е , э т о н е с л и ш к о м п р о я с н и л о с и т у а ц и ю ? Т о г д а в о т д о п о л н и т е л ь н о е пояснение:абстрактный м е т о д — это метод, описанный при п о м о щ и ключевого слова a b s t r a c t .Н и ч у т ь н е л е г ч е ? Т о г д а с л е д у ю щ е е д о б ь е т в а с о к о н ч а т е л ь н о : а б с т р а к т н ы й м е т о д н е имеет реализации.Теперь рассмотрим урезанную демонстрационную программу.//Abstractlnheritance//абстрактным,//методаnamespace-класспосколькувBankAccountнемнеявляетсясуществуетреализацииWithdraw()Abstractlnheritance{usingSystem;//AbstractBaseClass//которомabstractимеетсяpublic-создадимтолькоclassабстрактныйединственныйметодкласс,вOutput()AbstractBaseClass{//////absOutput - абстрактный метод,который выводит строку,но только в подклассах,которые перекрывают этотметодtractpublicvoid Output(stringsOutputString);}//302SubClassl-перваяконкретнаяреализацияклассаЧасть IV.
Объектно-ориентированное программирование//AbstractBaseClasspublic c l a s sSubClassl:AbstractBaseClass{overridepublicvoidOutput(stringsSource){strings=sSource.ToUpper();Console.WriteLine("ВызовSubClassl.Output()из{о}",s) ;}}//SubClass2//-ещеоднаконкретнаяреализацияклассаAbstractBaseClasspublicclassSubClass2:AbstractBaseClass{overridepublicvoidOutput(stringsSource){strings=sSource.ToLower();n rs oo gl re a. Wc l a s sC o PmriteLine("Вызовs) ;SubClass2.Output()из{0}",{publics t a t i cvoidTest(AbstractBaseClassba){ba.Output("Test");}publics t a t i cvoidMain(string []strings){// Нельзя создатьобъект класса AbstractBaseClass,// п о с к о л ь к у он — а б с т р а к т н ы й .
Если вы снимете// комментарий со следующей с т р о к и ,то С# сгенерирует// сообщение об ошибке компиляции// A b s t r a c t B a s e C l a s s ba= new A b s t r a c t B a s e C l a s s ( ) ;/ / Т е п е р ь п о в т о р и м наш э к с п е р и м е н т с к л а с с о м S u b c l a s s lConsole.WriteLine("СозданиеобъектаSubClassl");S u b C l a s s l s c l = new S u b C l a s s l ( ) ;Test(scl) ;// и к л а с с о м S u b c l a s s 2Console.WriteLine("\пСозданиеобъектаSubClass2");SubClass2sc2 = new S u b C l a s s 2 ( ) ;Test(sc2) ;// Ожидаем п о д т в е р ж д е н и я п о л ь з о в а т е л яConsole.WriteLine("Нажмите <Enter> для " +"завершения программы...");Console.Read();В программе с н а ч а л а о п р е д е л я е т с я к л а с с A b s t r a c t B a s e C l a s s с е д и н с т в е н н ы м абстрактнымметодомOutput ().Посколькуонобъявленкакabstract,методOutput ( ) н е и м е е т р е а л и з а ц и и , т.е.
т е л а м е т о д а .Глава 13. Полиморфизм303К л а с с A b s t r a c t B a s e C l a s s н а с л е д у ю т д в а п о д к л а с с а : S u b C l a s s l и SubClass2Оба — конкретные классы, так как перекрывают метод O u t p u t () "настоящими" методами и не содержат собственных абстрактных методов.К л а с с м о ж е т б ы т ь о б ъ я в л е н к а к а б с т р а к т н ы й н е з а в и с и м о от н а л и ч и я в нем абс т р а к т н ы х м е т о д о в .
О д н а к о к о н к р е т н ы м к л а с с м о ж е т б ы т ь т о г д а и только т огда, к о г д а в с е а б с т р а к т н ы е м е т о д ы в с е х б а з о в ы х к л а с с о в в ы ш е н е г о сокрыть(перекрыты) реальными методами.М е т о д ы O u t p u t ( ) д в у х р а с с м а т р и в а е м ы х п о д к л а с с о в н е м н о г о р а з л и ч н ы — один и зн и х п р е о б р а з у е т п е р е д а в а е м у ю е м у с т р о к у в в е р х н и й р е г и с т р , д р у г о й — в нижний. Вывод программы демонстрирует полиморфную природу класса A b s t r a c t B a s e C l a s s .СозданиеВызовобъектаСозданиеВызовSubClasslSubClassl.Output()объектаизSubClass2.Output()Нажмите<Enter>TESTSubClass2дляизt e s tзавершенияпрограммы...А б с т р а к т н ы й м е т о д а в т о м а т и ч е с к и я в л я е т с я в и р т у а л ь н ы м , т а к ч т о добавлятьключевое слово v i r t u a l к ключевому слову a b s t r a c t н е требуется.Создание абстрактных объектов невозможноО б р а т и т е в н и м а н и е е щ е на о д н у в е щ ь в р а с с м а т р и в а е м о й д е м о н с т р а ц и о н н о й прог р а м м е : нельзя создавать объект A b s t r a c t B a s e C l a s s , н о аргумент ф у н к ц и и Test()объявленкакобъекткласса A b s t r a c t B a s e C l a s sдополнение крайне важно.
Объекты S u b C l a s s lилиодногои SubClass2изегоподклассов. Этом о г у т б ы т ь переданыв функцию, поскольку оба являются конкретными подклассами A b s t r a c t B a s e C l a s s ,З д е с ь и с п о л ь з о в а н о о т н о ш е н и е Я В Л Я Е Т С Я . Э т о о ч е н ь м о щ н а я м е т о д и к а , позволяющаяписать высоко обобщенные методы.Д л я с о з д а н и я н о в о й и е р а р х и и н а с л е д о в а н и я м о ж н о т а к ж е и с п о л ь з о в а т ь ключ е в о е с л о в о v i r t u a l .
Р а с с м о т р и м и е р а р х и ю к л а с с о в , п о к а з а н н у ю в приведенной далее демонстрационной программе I n h e r i t a n c e T e s t .//InheritanceTest//v i r t u a lnamespaceдля-примерсозданияиспользованияновойиерархииключевогословаклассовInheritanceTest{using.System;publicclassProgram{publics t a t i cvoidMain(string[]strings){Console.WriteLine("\пПередачаBankAccount")BankAccount ba = new B a n k A c c o u n t ( ) ;304Часть IV. Объектно-ориентированное программированиеTestl(ba);Console.WriteLine("\пПередачаSavingsAccount");SavingsAccountsa = new S a v i n g s A c c o u n t ( ) ;Testl(sa) ;Test2(sa) ;Console.WriteLine("\пПередачаSpecialSaleAccount");SpecialSaleAccounts s a = new S p e c i a l S a l e A c c o u n t ( ) ;Testl(ssa);Test2(ssa) ;Test3(ssa) ;Console.WriteLine("\пПередачаS a l e S p e c i a l C u s t o m e r s s c = newTestl(ssc);Test2 (ssc)Test3(ssc) ;Test4(ssc) ;//ОжидаемподтвержденияSaleSpecialCustomer");SaleSpecialCustomer();пользователяConsole.WriteLine("Нажмите <Enter> для " +"завершения программы...");Console.Read();publics t a t i cvoidTestl(BankAccountConsole.WriteLine("\tBaccount.Withdraw(100)publics t a t i cvoidaccount)Test(BankAccount)");;Test2(SavingsAccountConsole .WriteLine ( " \ t Baccount)Test (SavingsAccount),") ;account.Withdraw(100);publics t a t i cvoidTest3(SpecialSaleAccountConsole.WriteLine("\tBaccount)Test(SpecialSaleAccount)");account.Withdraw(100);publics t a t i cvoidTest4(SaleSpecialCustomerConsole.WriteLine("\tBaccount)Test(SaleSpecialCustomer)");account.Withdraw(10 0);// B a n k A c c o u n t-// присваиваемымpublicclassмоделируетприбанковскийсоздании,исчетсномером,балансомBankAccounttaa 13.
Полиморфизм305//////W i t h d r a w a l - вы м о ж е т е с н я т ь со с ч е т а любую сумму,превышающую б а л а н с .Возвращает реально снятую сосчетасуммуv i r t u a lpublicvoidWithdraw(decimalнеdWithdraw){C o n s o l e . W r i t e L i n e ( " \ Ь \ Ь в ы з ы в а е т "•+11" B a n k A c c o u n t . W i t h d r a w ()) ;}}////SavingsAccountпроцентовpublicclass-банковскийSavingsAccountсчет:сначислениемBankAccount{overridepublicvoidWithdraw(decimalmWithdrawal){Console .WriteLine ("\t\tBbi3biBaeT " +"SavingsAccount.Withdraw()");}}////SpecialSaleAccountпродажpublicclass-счетиспользуетсяSpecialSaleAccount:толькодляSavingsAccount{newvirtualpublicvoidWithdraw(decimalmWithdrawal){Console .WriteLine ("\t\TBBI3BMAET " +"SpecialSaleAccount.Withdraw()");}}//SaleSpecialCustomer//покупателейpublicclass-счеттолькоSaleSpecialCustomer:дляспециальныхSpecialSaleAccount{overridepublicvoidWithdraw(decimalmWithdrawal){}}}Console .
WriteLine ("\t\TBBI3BIBAET " +"SaleSpecialCustomer.Withdraw()");К а ж д ы й из у к а з а н н ы х к л а с с о в р а с ш и р я е т н а с л е д у е м ы й к л а с с . З а м е т ь т е , однако, чтометодS p e c i a l S a l e A c c o u n t . W i t h d r a w ()помеченкак v i r t u a l ,чторазрывайц е п ь н а с л е д о в а н и я в э т о й т о ч к е .
П р и р а с с м о т р е н и и с т о ч к и з р е н и я B a n k A c c o u n t класс ы S p e c i a l S a l e A c c o u n t и S a l e S p e c i a l C u s t o m e r в ы г л я д я т в т о ч н о с т и как Savi n g s A c c o u n t . И только при рассмотрении с точки зрения S p e c i a l S a l e A c c o u n tстановятся доступны новые версии W i t h d r a w ( ) .В с е э т о п о к а з а н о в п р и в е д е н н о й д е м о н с т р а ц и о н н о й п р о г р а м м е . Ф у н к ц и я Main()в ы з ы в а е т р я д м е т о д о в T e s t ( ) , к а ж д ы й и з к о т о р ы х р а з р а б о т а н д л я с в о е г о подкласса,]306Часть IV.