CodeGym /Kurslar /C# SELF /Sinif iyerarxiyasının yaradılması

Sinif iyerarxiyasının yaradılması

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Təsəvvür elə, iyerarxiyasız bir dünya: minlərlə Person, Animal, Vehicle sinifi və bunların hamısı tamamilə ayrı. Heç təəccüblü deyil ki, belə bir dünyada proqramçılar nahara qədər belə yaşaya bilməzdilər — tamamilə çaşardılar! Real layihələrdə bizə tez-tez elə obyektlər lazımdır ki, onlar ümumi bir şey edə bilsinlər (məsələn, bütün heyvanlar hərəkət edə bilir), amma hərəsinin öz xüsusiyyətləri var (balıq üzür, quş uçur).

Məhz sinif iyerarxiyaları varlıqlar arasındakı əlaqəni ifadə etməyə imkan verir ki, proqramlaşdırma yaradıcı iş olsun, sonsuz copy-paste döyüşü yox.

Bir nümunəyə baxaq. Tutaq ki, bizdə baza Animal sinifi var. Bütün heyvanlar səs çıxara bilir. Amma yalnız pişiklər miyoldayır, itlər hürür, tutuquşular isə hətta bir-iki zarafat da danışa bilər. Biz bunu kodda iyerarxik şəkildə ifadə etmək istəyirik.

Baza sinif


public class Animal
{
    public string Name { get; set; }

    public Animal(string name)
    {
        Name = name;
    }

    // Baza metod: övladlarda override etmək olar
    public virtual void Speak()
    {
        Console.WriteLine("Heyvan hansısa bir səs çıxarır...");
    }
}

Burada biz virtual sözünü Speak() metoduna əlavə etdik. Bu bir işarədir: "Ey övlad siniflər, istəsəniz bu metodu override edə bilərsiniz".

Iyerarxiya yaradırıq: törəmə siniflər

İndi bizdə Cat sinifi olsun, o Animal-dan miras alacaq:


public class Cat : Animal
{
    public Cat(string name) : base(name) { }

    // Speak-i override edirik — pişiklər sadəcə guruldaya bilməz!
    public override void Speak()
    {
        Console.WriteLine($"{Name} deyir: Miyau!");
    }
}

Dog sinifi:

public class Dog : Animal
{
    public Dog(string name) : base(name) { }

    public override void Speak()
    {
        Console.WriteLine($"{Name} deyir: Hav!");
    }
}

Bəs əgər bizdə danışa bilməyən adi bir heyvan olsa? Onda baza sinifdən istifadə edə bilərik, heç nə override etmədən.

Vizualizasiya — iyerarxiya ağacı


.               Animal
                /   \
             Cat    Dog
  • Animal — baza sinif
  • Cat, Dog — övlad (törəmə) siniflər

2. Gəlin belə bir iyerarxiyanı istifadə edən kod yazaq

Konsol tətbiqimiz üzərində işləməyə davam edirik.

Tutaq ki, bizdə heyvanlar kolleksiyası var və istəyirik ki, hər biri özünəməxsus bir şey desin:

Animal[] zoo = new Animal[]
{
    new Cat("Barsik"),
    new Dog("Reks"),
    new Animal("Qəribə varlıq")
};

foreach (Animal animal in zoo)
{
    animal.Speak();
}

Gözlənilən çıxış:

Barsik deyir: Miyau!
Reks deyir: Hav!
Heyvan hansısa bir səs çıxarır...

Bax belə, iyerarxiya və polymorphism (tezliklə ətraflı baxacağıq, amma əsas məqam — obyektin real tipinə görə düzgün metod versiyası çağırılır) sayəsində tətbiqin çevik və genişlənə bilən olur.

3. Yeni metodlar və sahələr əlavə edirik

Deməli, "səsləndirmə" məsələsini həll etdik. Amma bütün heyvanlar — çox darıxdırıcıdır. Məsələn, pişiyin doqquz canı ola bilər, it isə çubuq gətirməyi bacarır.

Unikal davranış əlavə edirik

Övlad sinifdə öz metod və sahələrini əlavə etmək olar:


public class Cat : Animal
{
    public int Lives { get; private set; } = 9;

    public Cat(string name) : base(name) { }

    public override void Speak()
    {
        Console.WriteLine($"{Name} deyir: Miyau! Məndə {Lives} can var.");
    }

    public void LoseLife()
    {
        if (Lives > 0)
        {
            Lives--;
            Console.WriteLine($"{Name} bir canını itirdi. Qaldı: {Lives}");
        }
        else
        {
            Console.WriteLine($"{Name} artıq bütün canlarını istifadə edib!");
        }
    }
}

Kodda tətbiq edirik:

var barsik = new Cat("Barsik");
barsik.Speak();      // Barsik deyir: Miyau! Məndə 9 can var.
barsik.LoseLife();   // Barsik bir canını itirdi. Qaldı: 8

Yeni siniflər əlavə edirik: "zooparkı" genişləndiririk

Artıq törəmə siniflər yaratmağı bacarırsan. Məsələn, tutuquşu əlavə edək:

public class Parrot : Animal
{
    public Parrot(string name) : base(name) { }

    public override void Speak()
    {
        Console.WriteLine($"{Name} deyir: Salam, insan!");
    }

    public void Repeat(string phrase)
    {
        Console.WriteLine($"{Name} təkrar edir: {phrase}");
    }
}

İndi sistemi asanlıqla genişləndirirsən, köhnə koda toxunmadan:

var keshka = new Parrot("Keşa");
keshka.Speak();                 // Keşa deyir: Salam, insan!
keshka.Repeat("Oxu, tələbə!"); // Keşa təkrar edir: Oxu, tələbə!

4. Heyvanların davranışını müqayisə edirik

Növ Speak() metodu Öz sahəsi Əlavə davranış
Animal Bəli (virtual) Name
Cat Bəli (override) Lives LoseLife()
Dog Bəli (override)
Parrot Bəli (override) Repeat(string)

Sinif iyerarxiyası yaddaşda necə görünür (blok-sxem)

Animal (Name)
 ├── Cat (Lives)
 ├── Dog
 └── Parrot (Repeat)

5. Tətbiqimizdə praktika

Gəlin iyerarxiya ideyasını tətbiqə bağlayaq — məsələn, bizdə müxtəlif tipli tapşırıqlar var:

  1. Task (baza sinif): İstənilən tapşırıq — onun adı və yerinə yetirilmə statusu var.
  2. WorkTask (iş tapşırığı): Bundan əlavə deadline var.
  3. HomeTask (ev tapşırığı): Prioriteti ola bilər ("Çox vacib", "Elə də vacib deyil").

Baza sinifdən başlayaq:

public class Task
{
    public string Title { get; set; }
    public bool IsCompleted { get; private set; }

    public Task(string title)
    {
        Title = title;
    }

    public virtual void Complete()
    {
        IsCompleted = true;
        Console.WriteLine($"Tapşırıq \"{Title}\" yerinə yetirildi!");
    }
}

İndi iş tapşırığı əlavə edirik:

public class WorkTask : Task
{
    public DateTime Deadline { get; set; }

    public WorkTask(string title, DateTime deadline)
        : base(title)
    {
        Deadline = deadline;
    }

    public override void Complete()
    {
        base.Complete();
        Console.WriteLine($"İcra müddəti: {Deadline:d}");
    }
}

Və ev tapşırığı:

public class HomeTask : Task
{
    public string Priority { get; set; }

    public HomeTask(string title, string priority)
        : base(title)
    {
        Priority = priority;
    }

    // Əgər baza sinifdəki davranış kifayət edirsə, Complete-i override etməyə ehtiyac yoxdur
}

Proqramda tapşırıqlar siyahısı yaradırıq:

List<Task> tasks = new List<Task>
{
    new WorkTask("Hesabatı göndər", DateTime.Today.AddDays(2)),
    new HomeTask("Qabları yumaq", "Çox vacib"),
    new Task("Inheritance mövzusunda mühazirəni oxu")
};

foreach (Task task in tasks)
{
    Console.WriteLine($"Tapşırıq: {task.Title}");
    task.Complete();
}

Gözlənilən çıxış:

Tapşırıq: Hesabatı göndər
Tapşırıq "Hesabatı göndər" yerinə yetirildi!
İcra müddəti: 13.07.2025
Tapşırıq: Qabları yumaq
Tapşırıq "Qabları yumaq" yerinə yetirildi!
Tapşırıq: Inheritance mövzusunda mühazirəni oxu
Tapşırıq "Inheritance mövzusunda mühazirəni oxu" yerinə yetirildi!

Görürsən, necə rahatdır: bütün tapşırıqlar birlikdə saxlanılır, onları eyni cür işləyirik, fərqlilik isə lazım olan yerdə ortaya çıxır.

6. Inheritance istifadə edərkən tipik səhvlər

Səhv №1: virtual kimi işarələnməyən metodu override etməyə cəhd.
Əgər baza sinifdə metod virtual kimi işarələnməyibsə, onu törəmə siniflərdə override etmək olmur. Nəticədə polymorphism-in bütün elastikliyi itir, iyerarxiya isə mənasız olur.

Səhv №2: Varlıqlar arasında məntiqi əlaqə olmadan inheritance.
Əgər obyektlər məna baxımından bağlı deyilsə, inheritance istifadə etməyə dəyməz. Məsələn, Dairə həqiqətən Fiqur-dur, amma At kimi Nəqliyyat vasitəsi — artıq bir az şişirtmədir. İstisna — xüsusi kontekstlər (məsələn, orta əsr oyunu), burada belə əlaqə əsaslandırıla bilər.

Səhv №3: Həddindən artıq dərin iyerarxiyalar.
Əgər sinif strukturu çox dərinləşirsə (5–6 və daha çox səviyyə), kod oxunmaz, baxımsız və testolunmaz olur. Bu, artıq inheritance əvəzinə kompozisiya barədə düşünmək üçün siqnaldır.

Səhv №4: Baza konstruktorunu çağırmağı unutmaq.
Törəmə sinifdə yeni property əlavə edəndə, konstruktorunda base(...) çağırmağı unutmaq asandır. Bu, obyektin baza hissəsinin natamam və ya səhv inicializasiyasına və çətin tapılan bug-lara səbəb ola bilər.

1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
İrsiyyət anlayışı
İrsiyyət və siniflərin iyerarxiyası
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION