CodeGym /Kurslar /C# SELF /İnterfeys anlayışı və onun sintaksisi

İnterfeys anlayışı və onun sintaksisi

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

1. İnterfeys nədir?

Əgər abstrakt class — bu, qismən reallaşdırılmış "yarımfabrikat" şablondursa, interfeys — sadəcə tələblər siyahısıdır: hansı bacarıqlara malik olmalıdır həmin obyekt (class), ki, onu müəyyən abstrakt kontekstdə istifadə etmək mümkün olsun.

Proqramlaşdırmada interfeys — elə bil ki, obyektin davranışına dair "müqavilə" və ya "tələblər siyahısı"dır. O, public metodlar, property-lər, indexer-lər və event-lər toplusunu təsvir edir, hansı ki, bu interfeysi implementasiya edən class mütləq təqdim etməlidir. İnterfeys deyir: "Əgər sən, məsələn, IDriveable (sürə bilən) adlanmaq istəyirsənsə, zəhmət olmasa Drive()Stop() metodlarını təqdim et".

İnterfeysi belə təsəvvür etmək olar: İşçiyə Tələblər Siyahısı: məsələn, əgər sən "Aşpaz" işə götürmək istəyirsənsə, interfeysdə yazılacaq: "Yemək bişirməyi, yeməkləri təqdim etməyi, əllərini yumağı bacarmalıdır". Konkret aşpaz bu tapşırıqları necə həll edəcək — onun şəxsi işidir. Əsas odur ki, kənardan müqaviləyə uyğun işləsin.

Vacibdir: interfeys yalnız təqdim olunmalıdır deyir, necə olacağını yox.

OOP terminlərində qısa

  • İnterfeys obyektin xarici "görünüşünü" (API) təsvir edir: hansı əməliyyatları yerinə yetirə bilər.
  • Heç bir vəziyyət (field) saxlamır. Klassik anlayışda interfeyslər implementasiya saxlamır, amma müasir C# versiyalarında istisnalar var (məsələn, default metodlar), bunları sonra danışacağıq.
  • Bir class istədiyi qədər interfeys implementasiya edə bilər (class inheritance-dan fərqli olaraq!).

Həyatdan analogiya

USB-port — hamı bilir ki, ora mouse, klaviatura, flash, qulaqcıq, hətta kofeaparat (bəli, belə də olur!) qoşmaq olar. "Mouse"un içində nə var — fərq etmir, əsas odur ki, USB portu olsun və cihaz düzgün protokolu dəstəkləsin. Bax, bu interfeysdir!

İnterfeyslər niyə lazımdır?

  • Bağlılığı azaldır. Kod interfeyslə işləyir, konkret class-la yox. "İnterfeys səviyyəsində proqramlaşdırırıq".
  • Davranışın çoxsaylı inheritance-ını təmin edir: class bir neçə interfeys implementasiya edə bilər.
  • Standartlaşdırma: universal mexanizmlər yaratmaq olar: məsələn, müqayisə oluna bilən bütün obyektlər IComparable interfeysini implementasiya edir.
  • Test oluna bilənlik: konkret implementasiyanı testdə "stub" ilə əvəz etmək asandır.
  • Plugin-lik: mövcud koda toxunmadan yeni "modullar" əlavə etmək olar.

2. İnterfeys elanının sintaksisi

İndi isə — koda keçək! C#-da interfeys interface açar sözü ilə elan olunur, interfeys adları adətən I ilə başlayır:


// İnterfeys elanı
public interface IPrintable
{
    // Abstrakt metod — müqavilə
    void Print();

    // Property-lər də elan etmək olar
    string Name { get; set; }
}

Yadda saxla: interfeys metod və property-lərində implementasiya olmur (metodun bədəni yoxdur, yalnız signature — abstrakt metodlarda olduğu kimi).

İnterfeysin əsas xüsusiyyətləri

  • İnterfeysdə field (üzv dəyişən) elan etmək olmaz.
  • Bütün metodlar, property-lər, event-lər və indexer-lər default olaraq public-dir (implementasiyada da belə olmalıdır).
  • İnterfeys constructor saxlaya bilməz (çünki vəziyyəti yoxdur).
  • İnterfeysi implementasiya edən class-ın abstrakt və ya konkret olması fərq etmir.

İnterfeys işdə

Gəlin interfeysi bizim tədris tətbiqimizə inteqrasiya edək. İndi bizdə "çap oluna bilən" interfeysi (IPrintable) var, onu Report class-ı və məsələn, yeni Invoice class-ı implementasiya edir.

public interface IPrintable
{
    void Print();
    string Name { get; set; }
}

İndi bu interfeysi implementasiya edən class təyin edək:

public class Report : IPrintable
{
    public string Name { get; set; }

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

    // İnterfeys metodunun implementasiyası
    public void Print()
    {
        Console.WriteLine($"Hesabatın çapı: {Name}");
    }
}

İndi isə — tamamilə başqa class, amma eyni interfeys:

public class Invoice : IPrintable
{
    public string Name { get; set; }

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

    public void Print()
    {
        Console.WriteLine($"Qaimənin çapı: {Name}");
    }
}

İndi isə istənilən çap oluna bilən obyektlə işləyən metod yaza bilərik:

public static void PrintAnything(IPrintable printable)
{
    printable.Print(); // Bitti! Hesabatdır, yoxsa qaimə — fərq etmir, əsas odur ki, çap edə bilir.
}

Və istifadə nümunəsi:

var report = new Report("Aylıq hesabat");
var invoice = new Invoice("Qaimə #12345");

PrintAnything(report);  // Hesabatın çapı: Aylıq hesabat
PrintAnything(invoice); // Qaimənin çapı: Qaimə #12345

Bax belə, interfeyslər universal, genişlənə bilən və gözəl kod yazmağa imkan verir.

3. İnterfeyslərin implementasiyası

İnterfeysi class-a qoşmaq

İnterfeys class tərəfindən iki nöqtə ilə implementasiya olunur (bəli, inheritance kimi):

public class Ticket : IPrintable
{
    public string Name { get; set; }
    public void Print()
    {
        Console.WriteLine($"Biletin çapı: {Name}");
    }
}

Vacibdir: class interfeysin bütün üzvlərini implementasiya etməlidir. Implementasiya olunan üzvlər public olmalıdır.

Əgər heç olmasa bir üzv implementasiya olunmasa:

public class BrokenTicket : IPrintable
{
    // Print() implementasiyası buraxılıb
    public string Name { get; set; }
}
// Kompilyasiya xətası: 'BrokenTicket' interfeys üzvü 'IPrintable.Print()' implementasiya etmir

Bir neçə interfeys

Class bir neçə interfeysi vergüllə implementasiya edə bilər:

public interface IStorable
{
    void Store();
}

public class MultiPurposeDoc : IPrintable, IStorable
{
    public string Name { get; set; }
    public void Print()
    {
        Console.WriteLine("Sənədin çapı");
    }

    public void Store()
    {
        Console.WriteLine("Sənədin saxlanması");
    }
}

4. İnterfeyslər niyə lazımdır?

Bəlkə indi beynində belə bir fikir var: "Yaxşı, sintaksis aydındır. Bəs bu real həyatda niyə lazımdır, başqa cür yox, məhz bu kursda həyatımı çətinləşdirmək üçün?" Səni inandırıram! İnterfeyslər peşəkar proqramlaşdırmada ən çox istifadə olunan alətlərdəndir.

Məsuliyyətin bölüşdürülməsi və zəif bağlılıq (Decoupling / Loose Coupling):

  • Təsəvvür et, musiqi pleyeri hazırlayırsan. Onun üçün musiqinin haradan gəldiyi vacib deyil — lokal fayldan, internetdən, yoxsa CD-dən. Əsas odur ki, musiqi mənbəyi audio stream verə bilsin.
  • Sən IAudioSource interfeysini GetAudioStream() metodu ilə təyin edə bilərsən.
  • Onda səndə FileAudioSource, InternetAudioSource, CDAudioSource class-ları olacaq, hansılar ki, bu interfeysi implementasiya edir.
  • Pleyerin IAudioSource ilə işləyəcək, konkret tipi bilmədən. Sabah yeni mənbə çıxsa, məsələn, BluetoothAudioSource, pleyerin kodunu dəyişməyə ehtiyac yoxdur! Sadəcə yeni class yaz, IAudioSource implementasiya et. Bu, sistemi daha çevik və asan genişlənən edir. Bu zəif bağlılıqdır – komponentlər konkret implementasiyadan yox, abstraksiyadan (interfeys) asılıdır.

Polimorfizm və vahid işləmə:

PrintAnything nümunəsində gördüyümüz kimi, müxtəlif tipli obyektlər toplusuna sahib ola bilərsən, amma onları birləşdirən ümumi davranış interfeysdə təsvir olunub. Bütün bu obyektlərdə eyni metodu (Print()) çağıra bilərsən, qarşıda konkret nə olduğunu bilmədən — hesabat, qaimə, ya bilet. Bu, çox qısa və universal kod yazmağa imkan verir.

Test (Unit Testing):

Bəlkə də interfeyslərin ən vacib tətbiqlərindən biridir. Sistemin hansısa komponentini test edəndə, ona tez-tez başqa komponentlər lazımdır (məsələn, məlumatı saxlayan class, hansı ki, database ilə işləyən class-dan asılıdır).

Əsl DatabaseSaver class-ı vermək əvəzinə (test üçün real database tələb edir!), sadəcə IDataSaver interfeysini implementasiya edən "saxta" (mock) obyekt verə bilərsən. Bu "mock" obyekt sadəcə saxlanmanı imitasya edəcək, real database-ə müraciət etmədən. Bu, komponentləri izolyasiya olunmuş, tez və xarici asılılıqsız test etməyə imkan verir.

API və framework-lərin hazırlanması:

Kitabxana və ya framework yaradanda, developer-lərə "genişlənmə nöqtələri" vermək istəyirsən. İnterfeyslər bunun üçün idealdır. Deyə bilərsən: "Əgər komponentin mənim sistemimlə işləməsini istəyirsənsə, bu interfeysi implementasiya et". .NET-in standart kitabxanaları interfeyslərlə doludur (məsələn, IEnumerable<T>, IDisposable, IComparable<T>) – onlar ən geniş yayılmış ssenarilər üçün müqavilələr təyin edir.

Birbaşa interfeys səviyyəsində proqramlaşdırma (Programming to an Interface):

Təcrübəli developer-lər tez-tez deyir: "İnterfeys səviyyəsində proqramlaşdır, implementasiyada yox". Yəni, dəyişənin və ya metod parametrinin tipini təyin edəndə, konkret class (Car) yox, interfeys (IDriveable) istifadə et. Bu, kodunu daha çevik və implementasiya detalları ilə az bağlı edir, bir implementasiyanı başqası ilə asanlıqla əvəz etməyə imkan verir.

5. İnterfeyslərlə işləyərkən tipik səhvlər

Səhv №1: interfeysdən obyekt yaratmağa cəhd.
Cat murzik = new Cat("Murzik", 3); yaza bilərsən, çünki Cat konkret class-dır. Amma yaza bilməzsən ITalkable talker = new ITalkable();. İnterfeys — sadəcə müqavilə, şablondur. O, implementasiya saxlamır və birbaşa yaradıla bilməz. Bu, layihədir, hazır ev yox.

Səhv №2: interfeysin bütün üzvlərinin implementasiyası unudulub.
Əgər class-ın interfeysi implementasiya etdiyini göstərmisənsə, məsələn IMyInterface, o mütləq bütün metodlarını implementasiya etməlidir. Bir metod belə buraxılsa, kompilyasiya xətası olacaq: MyClass IMyInterface.TheMissingMethod() implementasiya etmir.

Səhv №3: implementasiyada səhv access modifier-lər.
İnterfeys metodları default olaraq public-dir və implementasiyada da public olmalıdır. Əgər private və ya protected etmək istəsən, kompilyator xəta verəcək. Söz vermisənsə — açıq implementasiya et.

Səhv №4: interfeysə field və ya constructor əlavə etməyə cəhd.
İnterfeyslər davranışı təsvir edir, vəziyyəti yox. Ona görə də field və ya constructor əlavə etmək olmaz. Əgər cəhd etsən — kompilyasiya xətası alacaqsan. Yalnız property-lər icazəlidir, o da — getter/setter təsviri kimi.

Səhv №5: override və interfeys implementasiyası arasında qarışıqlıq.
override açar sözü baz class metodunu override etmək üçündür. Amma interfeys implementasiyasında lazım deyil — sadəcə public metod yaz, düzgün signature ilə. Bu, asanlıqla gözdən qaçan vacib nüansdır.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION