Савол ва топшириқлар
Индексатор нима? Уни нима учун қўллаш мумкин?
Статик конструктор экземпляр майдонини инициализация қила оладими?
Метод ва амалларни қайта юклаш нима учун керак?
Амалларни қайта юклаш усулларини айтиб беринг.
Қандай класслар учун қайта юкланган амаллардан фойдаланиш мумкин?
қандай типлар класснинг унар амал параметрига эга бўлади?
Ташқи муҳитдан дастурга параметрларни қандай қилиб узатилади?
21-маъруза
Синфлар ворислиги
Режа:
Ворислик. Авлод-синфларни тавсифлаш Виртуал метод Абстракт синфлар Бепушт синфлар Синфлар ўртасидаги муносабатларнинг кўринишлари
Хар ҳил типлаги синфларни бошқариш мушкул вазифа. Бу муаммони синфларни тартиблаш ёки занжирлаш (бир нечта синфларни бирлаштириб, ҳусусиятларини умумийлаштириш ва ундан базавий синф сифитида фойдаланиш) орқали ҳал қилиш мумкин.
Дастурчиларга бундай имкониятларни ОЙДнинг қудратли воситаларидан бири бўлган ворислик механизми тақдим этиши мумкин. Ворислик авлод-синфлар ўз аждодларининг ҳусусиятларини қабул қилиши мумкин бўлган шажараларни ташкил қилиш имконини беради. Сўнгра авлод-синфлар ҳусусиятларини тўлдириш мумкин. Шундай қилиб, ворислик кодлардан кўп марта фойланиш имконини яратади.
Шажара бошига яқин турган синфлар ўзидан қуйида турган синфларнинг ҳаммаси учун ҳос бўлган аломатларга эга бўлади. Синфлар шажара бўйича қуйига қараб сурилгани сари кўпроқ конкрет ҳусиятларга эга бўлиб боради.
Авлод-синфларни тавсифлаш
C# дастурлаш тилида объектлар иҳтиёрий сондаги авлодларга ва фақат битта аждодга эга бўлиши мумкин. Синфларни тавсифлашда уларнинг аждоди синф сарлавҳасида икки нуқта (:) белгисидан кеийн ёзилади. Агара влод номи кўрсатилмаган бўлса, аждод бўлиб System.Object шажараси тўлалигича базавий синф деб ҳисобланади:
[ атрибутлар ] [ спецификаторлар ] class синф _номи [ : аждод ]
Синф жисми
Синфлар корислигини мисол орқали қўрайлик. Илгари компьютер ўйинлари персонажларини ифодалаш учун Monster синфи эълон қилинган эди. Фараз қилайлик, бизга унинг ҳусусиятларига эга бўлиб, қўшимча ўйлаши хам мумкин бўлган яна битта персонаж керак бўлсин. Янги объектни Monster объектининг авлоди деб қараш мақсадаг мувофиқ бўлади. (21.2.1-листинг)
using System;
namespace ConsoleApplication1
{
class Monster
{
...
}
class Daemon : Monster
{
public Daemon()
{
brain = 1;
}
public Daemon( string name, int brain ) : base( name ) // 1
{
this.brain = brain;
}
public Daemon( int health, int ammo, string name, int brain )
: base( health, ammo, name ) // 2
{
this.brain = brain;
}
new public void Passport() // 3
{
Console.WriteLine(
"Daemon {0} \t health = {1} ammo = {2} brain = {3}",
Name, Health, Ammo, brain );
}
public void Think() // 4
{
Console.Write( Name + " is" );
for ( int i = 0; i < brain; ++i ) Console.Write( " thinking" );
Console.WriteLine( "..." );
}
int brain; // закрытое поле
}
class Class1
{ static void Main()
{
Daemon Dima = new Daemon( "Dima", 3 ); // 5
Dima.Passport(); // 6
Dima.Think(); // 7
Dima.Health -= 10; // 8
Dima.Passport();
}
}
}
21.2.1-листинг. Monster kлассining avlodo bo'lgan Daemon klassi.
Daemon синфида ёпиқ brain майдони хамда Think методлари аниқланган, шунинргдек ҳусусий конструкторлар киритилган ва Passport метод қайта аниқланган. Daemon синфи ворис сифатида Monster синфининг барча ҳусусият ва методларини қабул қилган.
Дастурнинг натижаси қуйидагича:
Daemon Dima health = 100 ammo = 100 brain = 3
Dima is thinking thinking thinking...
Daemon Dima health = 90 ammo = 100 brain = 3
Кўририб турибдки, Daemon синфи экземпляри осонлик билан ҳусусий операторлар) ва аждодидан қабул қилган элементлардан (8-оператор) фойдаланмоқда. Вроисликнинг умумий қоидаларини кўриб чиқайлик.
Конструкторларни ворис ўзига қабул қила олмайди, шунинг учун ҳосила синф ҳусусий конструкторига эга бўлиши лозим. Конструкторлар қуйидагича усулда чақирилиши мумкин.
Агар ҳосила синф конструкторида базавий синфнинг конструктори ошкор усулда чақирилмаса, тўғридан – тўғри базавий синфнинг параметрсиз конструктори чақирилади..
Бир нечта тармоқдан иборат шажара учун базавий синфларнинг к конструкторлари энг юқори тармоқдан бошлаб чақирилади. Бундан кейин объект тарзида эълон қилинган синф конструкторлари, сўнгра синф конструкторлари бажарилади. Шундай қилиб, ҳар бир конструктор объект учун ўз қисмини инициализация қилади.
Агар базавий синф конструктори параметрлар кўрсатишни талаб қилса, у холда у ҳосила синф конструкторида ошкор усулда чақирилиши лозим. Чақириш base хизматчи сўзи ёрдамида амалга оширилади. Бу холда параметри base хизматчи сўзидан кейин кўрсатилган аргументлар рўйхатига мос келувчи конструктор чақирилади.
Ворис аждодининг майдон, методлар ва ҳусусиятларини қабул қилиши мумкин, шунинг учун базавий синф элементини янги элемент билан алмаштиришга зарурат туғилганда компиляторга бу ҳақда new хизматчи сўзи билан хабар бериш лозим. 21.2.2-листингда шу усул билан Passport объекти ҳақидаги маълумотларни экранга чиқариш методи қайта аниқланган. Daemon синфининг Passport методи базавий синфнинг кмос методини алмаштиради, аммо ҳосила синфдан базавий синф методларига мурожаатқ илиш имконияти сақланади. Бунинг учун методга мурожаат қилишдан аввал base хизматчи сўзини ёзиш керак. Масалан:
base.Passport();
private тарзида эълон қилинган базавий синф элементлари ҳоисла синфи учун ёпиқ. Шунинг учун Passport методида name, health хамда ammo майдонларига ўтиш имконяитига эга бўлиш учун базавий синфнинг мос ҳусусиятидан фойдаланишга тўғри келди. Агар бу майдонлар protected спецификатори билан тавсифланган бўлса, у холда бу майдонлар Monster нинг барча ҳосила синфларининг методлари учун очиқ бўлади.
Дастурниг бажарилиш вақтида объектлар алоҳида ўзгарувчи, масиив ёки коллекцияларда сақланади. Кўпинча битта шажара объектлари устида бир хил амалларни бажариш, яъни, битта дастур кодидан турли синф экземплярлари учун фойдаланиш қулай ҳисобланади. Бу холат базавий синф объектига тҳосила синф объектларини ўзлаштириш мумкинлигидан келиб чиқади.
Базавий синф объектлари массивини тавсифлашга ва унга ҳосил синф объектларини жойлашга уриниб кўрамиз. 21.2.3-листингда Monster массивида Monster типидаги иккита объект хамда битта Daemon типидаги объект сақланади..
using System;
namespace ConsoleApplication1
{
class Monster
{
...
}
class Daemon : Monster
{
... //
}
class Class1
{ static void Main()
{
const int n = 3;
Monster[] stado = new Monster[n];
stado[0] = new Monster( "Monia" );
stado[1] = new Monster( "Monk" );
stado[2] = new Daemon ( "Dimon", 3 );
foreach ( Monster elem in stado ) elem.Passport(); // 1
for ( int i = 0; i < n; ++i ) stado[i].Ammo = 0; // 2
Console.WriteLine();
foreach ( Monster elem in stado ) elem.Passport(); // 3
}
}
}
21.2.3-листинг. Турли типдаги объектлар массиви
Дастурнинг натижаси қуйидагича:
Monster Monia health = 100 ammo = 100
Monster Monk health = 100 ammo = 100
Monster Dimon health = 100 ammo = 100
Monster Monia health = 100 ammo = 0
Monster Monk health = 100 ammo = 0
Monster Dimon health = 100 ammo = 0
Натижа бизни қисман қаноатлантириши мумкин: ҳақиқатдан ҳам Daemon типидаги объектни Monster типидаги объектлардан ташкил топган массивга жойлаштириш мумкин, аммо уни фақат аждодидан олган ҳусусият ва методлар билан чақириш мумкин. Бу амални 2-оператор таъминлайди.
Шундай қилиб, базавий синф объектига хосил синф объектини ўзлаштириш мумкин, аммо унинг учун фақат базавий синф ҳусусият ва методлари чақирилади. Бошқача айтганда улар билан ишлаш имконияти фақат ҳаволалар типидаги объектлар орқали яратилади холос.
Бу тушунарли: ахир компилятор дастур бажарилгунча қайси методни чақириш кераклигини аниқлаши ва кодга бу методга мурожаатни жойлаштириш лозим. Бу жараённи эрта боғланиш деб аталади. Бунда компилятор фақат метод чақириладиган ўзгарувчиларнинг типига суянади (масалан, stado[i].Ammo ). Бу ўзгарувчида турли вақт мобайнида турли типдаги объектларга ҳаволалар жойлашган бўилши мумкинлигини компилятор хисобга ола олмаслиги мумкин.
Демак, чақирилаётан методлар объектлар типига мос бўлиши учун Следовательно, агар млар хотим, чтоблар вызываемые методлар боғлаш жараёнини дастурнинг бажарилиш босқичигача, аниқроғи ҳавола қайси типдаги объектга кўрсатиши аниқ бўлганда метод чақирилгунча тўхтатиб туриш лозим. Бундай механизм C# дастурлаш тилида мавжуд ва у кечки боғланиш деб аталади хамда виртуал методлар ёрдамида амалга оширилади.
Do'stlaringiz bilan baham: |