Hosil qilingan sinfdan tayanch sinf a'zolariga kirish

Hosil qilingan sinfdan tayanch sinf a'zolariga kirish
Per_son va Emp_loyee sinflariga qaytamiz. E_mployee o'zining barcha funktsiyalarini Person sinfidan olgan bo'lsa-da, keling quyidagi holatda nima bo'lishini ko'rib chiqaylik:
class Employee : Person
{
public void Display()
{
Console.WriteLine(_name);
}
}
Ushbu kod ishlamaydi va xatoga yo'l qo'yadi, chunki _name o'zgaruvchisi xususiy modifikator bilan e'lon qilinadi va shuning uchun unga faqat Person sinfi kirish huquqiga ega. Boshqa tomondan, Person sinfida biz foydalanishimiz mumkin bo'lgan N_ame umumiy xossasi mavjud, shuning uchun quyidagi kod biz uchun yaxshi ishlaydi:
class Employee : Person
{
public void Display()
{
Console.WriteLine(Name);
}
}
Shunday qilib, olingan sinf faqat p_rivate p_rotected (agar baza va olingan sinf bir joyda bo'lsa), public, in_ternal (agar baza va hosilaviy sinf bir to`plamda bo'lsa), p_rotected, p_rotected va internal. modifikatorlari bilan aniqlangan bazaviy sinf a`zolariga murojaat qila oladi.
Base kalit so'z
Endi sinflarimizga konstruktorlarni qo'shaylik: class Person
{
public string Name { get; set; }
public Person(string name)
{
Name = name;
}
public void Display()
{
Console.WriteLine(Name);
}
}
class Employee : Person
{
public string Company { get; set; }
public Employee(string name, string company)
: base(name)
{
Company = company;
}
}
PeGrson sinfida Name xususiyatini o'rnatuvchi konstruktor mavjud. Egmployee sinfi bir xil Name xususiyatini voris qilib olganligi va o'rnatganligi sababli, o'rnatish kodini yuz marta yozmaslik, lekin qandaydir tarzda Person sinfining tegishli kodini chaqirish mantiqan to'g'ri bo'ladi. Bundan tashqari, asosiy sinf konstruktorida o'rnatilishi kerak bo'lgan yana bir qancha xususiyatlar va parametrlar bo'lishi mumkin.
Asosiy kalit so'z bilan biz asosiy sinfga murojaat qilishimiz mumkin. Bizning holatimizda biz Employee sinfining konstruktorida nom va kompaniyani belgilashimiz kerak. Ammo biz o'rnatish uchun nomni bazalik sinfning konstruktoriga, ya'ni Person sinfining konstruktoriga base (name) iborasi yordamida beramiz.
static void Main(string[] args)
{
Person p = new Person("Bill");
p.Display();
Employee emp = new Employee ("Tom", "Microsoft");
emp.Display();
Console.Read();
}
Hosilaviy sinflarda konstruktorlar
Konstruktorlar voris olayotganda hosilaviy sinfga o'tmaydi. Agar bazaviy sinf parametrlarsiz standart konstruktorni aniqlamasa, faqat parametrlarga ega bo'lgan konstruktorlarni (Person bazasi bilan bo'lgani kabi) aniqlasa, u holda hosil bo'lgan sinfda ushbu konstruktorlardan birini base kalit so'z orqali chaqirishimiz kerak. Masalan, Employee sinfidan konstruktor aniqlanishini olib tashlansa:
class Employee : Person
{
public string Company { get; set; }
}
Bunday holda, biz xatoga yo'l qo'yamiz, chunki Employee sinfi Person sinfiga mos kelmaydi, ya'ni asosiy sinf konstruktorini chaqirmaydi. Agar biz bir xil xususiyatlarni o'rnatadigan biron bir konstruktorni qo'shsak ham, biz xatoga yo'l qo'yamiz:
public Employee(string name, string company)
{
Name = name;
Company = company;
}
Ya'ni, Employee sinfida base kalit so'z orqali Person sinfining konstruktorini aniq chaqirishingiz kerak:
public Employee(string name, string company)
: base(name)
{
Company = company;
}
Shu bilan bir qatorda, biz asosiy sinfda parametrsiz konstruktorni aniqlay olamiz:
class Person
{
// sinfning qolgan kodi
//standart konstruktor
public Person()
{
FirstName = "Tom";
Console.WriteLine("parametsiz konstruktorni chaqirish");
}
}
Keyin asosiy sinfning konstruktoriga havola bo'lmagan har qanday hosil qilingan sinfning har qanday konstruktorida ushbu standart konstruktor hali ham yashirincha chaqiriladi. Masalan, quyidagi konstruktor
public Employee(string company)
{
Company = company;
}
Aslida quyidagi konstruktorga teng bo'ladi:
public Employee(string company)
:base()
{
Company = company;
}
Konstruktorga chaqirish tartibi
Sinf konstruktori chaqirilganda, avval asosiy sinflarning konstruktorlari qayta ishlanadi, shundan keyingina hosilaviy sinflarning konstruktorlari chaqiriladi. Masalan, quyidagi sinflarga e`tibor bering:
class Person
{
string name;
int age;
public Person(string name)
{
this.name = name;
Console.WriteLine("Person(string name)");
}
public Person(string name, int age) : this(name)
{
this.age = age;
Console.WriteLine("Person(string name, int age)");
}
}
class Employee : Person
{
string company;
public Employee(string name, int age, string company) : base(name, age)
{
this.company = company;
Console.WriteLine("Employee(string name, int age, string company)");
}
}
Employee ob`ektini yaratishdan keyin:
Employee tom = new Employee("Tom", 22, "Microsoft");
Quyidagi natijaga ega bo`lamiz:
Person(string name)
Person(string name, int age)
Employee(string name, int age, string company)
Natijada biz quyidagi bajariladigan zanjirga ega bo`lamiz:
Employee(string name, int age, string company) konstruktori birinchi bo'lib chaqiriladi. UPerson (string nomi, int age) konstruktoriga bajarushni topshiradi
Person(string name, int age) konstruktori chaqiriladi, uning o'zi hali bajarilmagan va bajarilishini Person(string name) konstruktoriga topshiradi.
Person(string name) konstruktori chaqiriladi va bajarilishini System.Object sinfining konstruktoriga topshiradi, chunki bu Person uchun standart bo'yicha bazaviy sinf.
System.Object.Object () konstruktori bajariladi, so'ngra Person(string name)konstruktoriga qaytariladi.
Person(string name) konstruktorining tanasi bajariladi, so'ngra bajaruv Person(string name, int age) konstruktoriga qaytariladi
Person(string name, int age) konstruktorining tanasi bajariladi, so'ngra bajarish Employee(string name, int age, string company) konstruktorga qaytadi.
Employee(string name, int age, string company) Konstruktor tanasi bajariladi. Natijada, Employee ob'ekti yaratiladi
|