CodeGym /Kurslar /C# SELF /Bir neçə interface-in reallaşdırılması

Bir neçə interface-in reallaşdırılması

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

1. Niyə bir neçə interface reallaşdırmaq lazımdır?

Real sistem dizayn edəndə obyektlər çox vaxt bir "rol" yox, bir neçə rol oynayır. Təsəvvür elə: səndə elektron kitab var, onu təkcə oxumaq yox, həm də redaktə etmək, hətta buluda saxlamaq olar. Obyekt-yönümlü proqramlaşdırma (OOP) terminlərində bu o deməkdir ki, obyekt bir neçə interface-i reallaşdırmalıdır:

  • IReadable — kontentin oxunması.
  • IWritable — kontentin redaktəsi.
  • ISyncable — uzaq storage ilə sinxronizasiya.

Bax, məhz burada bir neçə interface-i reallaşdırmaq imkanı işə düşür. Bu — C#-ın (və ümumiyyətlə OOP-nin) super gücüdür, class-larda bu yoxdur: sən iki və ya daha çox class-dan irs ala bilməzsən, amma istədiyin qədər interface reallaşdıra bilərsən.

Real həyatdan analogiya

Bir şirkətdə işçini təsəvvür elə. Vasiya eyni anda ola bilər:

  • Proqramçı (kod yazır)
  • Testçi (bəzən başqasının kodunu yoxlayır)
  • Menecer (sprintləri və ya gündəlik kofe normasını planlaşdırır)

Bu "rolların" tamamilə fərqli vəzifələri var. Amma Vasiya hər bir "müqavilə" ilə rahat başa çıxır! Proqramlaşdırmada da eyni: class interface-ləri reallaşdırır və onların "vəzifələrini" öz üzərinə götürür.

2. Bir neçə interface-in reallaşdırılmasının sintaksisi

Çox sadədir: class elan edəndə interface-ləri vergüllə ayırırsan:


public interface IReadable
{
    void Read();
}

public interface IWritable
{
    void Write(string text);
}

public class Note : IReadable, IWritable
{
    private string content = "";

    public void Read()
    {
        Console.WriteLine("Qeyd: " + content);
    }

    public void Write(string text)
    {
        content = text;
        Console.WriteLine("Qeyd yeniləndi!");
    }
}

Bu nümunədə Note class-ı hər iki interface-i reallaşdırır. Deməli, onda hər iki metodun reallaşdırılması mütləq olmalıdır: həm Read, həm də Write.

3. Bu "bizim" tətbiq nümunəsində necə görünür

Əvvəlki nümunələrimizdə biz sadə bank tətbiqi qururduq. İndi fərz edək: sənə universal bir sənəd class-ı lazımdır, onu çap etmək (IPrintable), fayla saxlamaq (ISavable) və bəlkə də e-mail-ə göndərmək (IEmailable) olar.

Interface-ləri təyin edirik:


public interface IPrintable
{
    void Print();
}

public interface ISavable
{
    void Save(string filePath);
}

public interface IEmailable
{
    void Email(string toAddress);
}

Hər şeyi birdən reallaşdıran class:


public class Statement : IPrintable, ISavable, IEmailable
{
    public string Content { get; set; }

    public void Print()
    {
        Console.WriteLine("Çap edirəm...");
        Console.WriteLine(Content);
    }

    public void Save(string filePath)
    {
        // Standart kitabxanadan File.WriteAllText istifadə edirik.
        File.WriteAllText(filePath, Content);
        Console.WriteLine($"Sənəd fayla saxlanıldı: {filePath}");
    }

    public void Email(string toAddress)
    {
        Console.WriteLine($"Sənəd e-mail-ə göndərildi: {toAddress} (simulyasiya)");
    }
}

İndi bu class-ı istədiyin kimi kodda istifadə edə bilərsən:


var stat = new Statement { Content = "Ay üzrə əməliyyatlar: +1000 vahid, -500 vahid." };
stat.Print();
stat.Save("statement.txt");
stat.Email("boss@bank.corp");

Yeri gəlmişkən, praktikada belə obyektləri metodlara ötürmək çox rahatdır, hansı ki, konkret interface tələb edir, qalan imkanlarına fikir vermədən. Məsələn, çap üçün metod IPrintable parametrini qəbul edə bilər və içində nə olduğunu bilməz — həm "saxlayan", həm də "poçtçu" ola bilər.

4. Interface referenslərinin tətbiqi: obyektimin nə bacardığı harada "görünür"?

Bax burada magiya başlayır. Bir neçə interface reallaşdıranda, obyektə yalnız onun müqavilələrindən biri kimi müraciət edə bilərsən. Məsələn:


IPrintable printable = new Statement { Content = "Abstraksiya üzrə mühazirə" };
printable.Print(); // Yalnız çap etmək olar

// printable.Save("file.txt"); // Səhv: IPrintable interface-i Save haqqında heç nə bilmir.

Amma başqa interface-ə keçsək:


ISavable savable = printable as ISavable;
if (savable != null)
{
    savable.Save("file.txt");
}

Bu rahatdır, obyektləri müəyyən interface referensinə qəbul edən metoda ötürəndə. Belə yanaşma bağlılığı azaldır və kodu çox çevik edir: yeni reallaşdırmalar əlavə edə bilərsən, köhnə kodu dəyişmədən.

5. Çoxlu reallaşdırma və fərqli interface-lərdə eyni adlı metodlar

Bax burada maraqlı şeylər başlayır! Bəs iki interface eyni adlı, amma fərqli məna daşıyan metod tələb edirsə? Məsələn, kofe maşını üçün interface-ləri təsəvvür elə:


public interface IStartable
{
    void Start();
}

public interface IRunnable
{
    void Start();
}

Kofe maşını həm "başlanğıc verilə bilən" (IStartable — içki hazırlanmasına start verir), həm də "runnable" (IRunnable — ümumiyyətlə işləməyə başlayır) ola bilər.

Default (adi) reallaşdırma:


public class CoffeeMachine : IStartable, IRunnable
{
    public void Start()
    {
        Console.WriteLine("Kofe maşını hər iki rol üzrə start verir!");
    }
}

Bu halda bir Start() reallaşdırması hər iki interface-i "bağlayır".

Bəs fərqli məna lazımdırsa?

Aydın interface reallaşdırması istifadə etmək olar:


public class CoffeeMachine : IStartable, IRunnable
{
    void IStartable.Start()
    {
        Console.WriteLine("Start: içki hazırlanmasına başlandı!");
    }

    void IRunnable.Start()
    {
        Console.WriteLine("Start: maşın iş rejiminə keçirildi.");
    }
}

Bu halda konkret reallaşdırmanı yalnız interface dəyişəni ilə çağırmaq olar:


CoffeeMachine cm = new CoffeeMachine();

IStartable startable = cm;
startable.Start(); // Start: içki hazırlanmasına başlandı!

IRunnable runnable = cm;
runnable.Start(); // Start: maşın iş rejiminə keçirildi.

// cm.Start(); // Compile olunmayacaq! Start class-ın özündə metod kimi əlçatan deyil.

Yeri gəlmişkən, bu üsul .NET standart kitabxanasında tez-tez istifadə olunur — məsələn, class bir neçə oxşar interface-i müxtəlif framework-lardan reallaşdıranda və hər biri öz davranışını tələb edəndə.

6. Bir neçə interface-in reallaşdırılması və irsiyyət fərqi

İmkan Class (irsiyyət) Interface-lər
Bazis tip sayı Yalnız bir İstədiyin qədər
Kodun irsiyyəti Bəli (bazis reallaşdırma mümkündür) Xeyr, yalnız imzalar (default metodlar istisna olmaqla)
State saxlamaq Bəli Xeyr
Yeni rol əlavə etmək Xeyr (və ya çətin, kompozisiya ilə) Asan, interface reallaşdır
Daha yaxşıdır... "Fiziki" iyerarxiyalar üçün "Rollar"/loji imkanlar üçün

7. Praktik tətbiq: "hibrid" obyektlər

Çoxlu interface reallaşdırması sayəsində, sən istədiyin "rol" kombinasiyası ilə class-lar düzəldə bilərsən, lazımsız irsiyyət barədə düşünmədən.

Məsələn, bizim bank tətbiqində — elə bir class düzəltmək olar ki, həm öz məlumatını saxlasın, həm özünü validasiya etsin, həm də çap etsin — hamısı müxtəlif interface-lərlə:


public interface IValidatable
{
    bool Validate();
}

public class Check : IPrintable, ISavable, IValidatable
{
    public string Data { get; set; }

    public void Print()
    {
        Console.WriteLine("Çek çapı: " + Data);
    }

    public void Save(string filePath)
    {
        File.WriteAllText(filePath, Data);
        Console.WriteLine("Çek saxlanıldı: " + filePath);
    }

    public bool Validate()
    {
        return !string.IsNullOrEmpty(Data);
    }
}

Belə yanaşma asan genişlənən arxitekturalar qurmağa imkan verir, class-lar lazım olduqca rolları kombinə edir. Yeni "vəzifə" əlavə etmək lazım olsa — sadəcə yeni interface reallaşdır.

8. Tipik səhvlər və tələlər

Yeni başlayanların tez-tez etdiyi səhv: interface-in bütün üzvlərini reallaşdırmağı unutmaq. Kompilyator burada bağışlamır — səhv atır və nə çatışmadığını göstərir. Belə səhvi başa düşmək asandır: "Class interface üzvünü reallaşdırmalıdır".

İkinci tez rast gəlinən problem — metodların əlçatanlığı ilə qarışıqlıq. Əgər metodu aydın reallaşdırmısansa, o class dəyişəni ilə əlçatan deyil — yalnız interface ilə.

Daha bir tipik vəziyyət — refaktoring: interface-də dəyişiklik edirsən (məsələn, metod əlavə etdin), amma bütün reallaşdırmaları yeniləmədin. Bu, kompilyasiya səhvlərinə gətirib çıxarır. Ona görə də dizayn zamanı çalış ki, interface-ləri çoxlu class istifadə edəndən sonra dəyişməyəsən.

2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
Bir neçə interfeys üçün sadə bir sinifin reallaşdırılması
Bir neçə interfeys üçün sadə bir sinifin reallaşdırılması
2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
İnterfeys istinadlarından istifadə
İnterfeys istinadlarından istifadə
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION