CodeGym /Kurslar /C# SELF /Abstrakt metodlar və property-lər

Abstrakt metodlar və property-lər

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

1. Abstrakt metodlar

Əvvəlki mühazirədə biz əsasları qoyduq: abstrakt class-larla tanış olduq və gördük ki, onlar abstrakt metodlar və property-lər saxlaya bilirlər. Başa düşdük ki, bu bir "kontrakt"-dır, hansı ki, miras alan class-ları öz implementasiyasını verməyə məcbur edir.

İndi isə gəlin detallara enək və daha mürəkkəb, praktik ssenarilərə baxaq. Bu mühazirədə biz sintaksisin nüanslarına, abstraksiyanın çoxsəviyyəli iyerarxiyalarda necə işlədiyinə fokuslanacağıq və dəqiq ayıracağıq ki, nə vaxt abstract, nə vaxt isə virtual istifadə etmək lazımdır.

Abstrakt metod köhnə bir aşpaz kitabından sirli reseptə bənzəyir: "gizli inqrediyent əlavə et" — hansı, deyilməyib, amma bütün sonrakı aşpazlar nəsə tapmalıdır!

Abstrakt metod həmişə abstrakt class-da olur

Adi (abstrakt olmayan) class-da abstrakt metod elan etməyə cəhd etsən, compiler səhv verəcək. Niyə? Çünki adi class-ı birbaşa yaratmaq olar, bəs təsvir olunmamış metodu çağırmağa cəhd etsək nə olacaq? Yalnız IDE-dən sirli bir baxış alacaqsan.


// Bu compile səhvi verəcək:
public class WrongClass
{
    public abstract void Oops(); // Belə etmək olmaz!
}

Əgər class-da heç olmasa bir abstrakt metod varsa, o mütləq abstract kimi işarələnməlidir!

Abstrakt metodların törəmə class-larda implementasiyası

Implementasiya override açar sözü ilə edilir. Abstrakt class-ı miras alan və bütün abstrakt metodları implementasiya etməyən class özü də abstrakt olmalıdır (yoxsa compiler əsəbləşəcək).

Tətbiqimizin ideyasını davam etdirək:

Əvvəlki mühazirələrdə biz Shape (fiqur) class-ını yaratmışdıq, orada sahənin hesablanması üçün abstrakt metod elan etmişdik. İndi isə konkret fiqurlar yaradaq:


public class Rectangle : Shape
{
    public double Width { get; }
    public double Height { get; }

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public override double CalculateArea()
    {
        return Width * Height;
    }
}

public class Circle : Shape
{
    public double Radius { get; }

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}

Niyə abstrakt metodlar bu qədər vacibdir?

Abstrakt metodlar — bu sənin demək üsulundur: "Uşaqlar, əgər bu class-ı miras alırsınızsa, qərar verin, bu necə işləməlidir!" Bu proqramın arxitekturasını daha aydın edir, təsadüfi buraxılışlardan qoruyur və ən əsası, polimorfizmdən tam istifadə etməyə imkan verir.

2. Abstrakt property-lər

Abstrakt property nədir

Abstrakt property — bu da abstrakt metod kimi kontraktdır, sadəcə property (property) üçün. C# üçün bu çox təbiidir, çünki property-lər məlumatı enkapsulyasiya etməyin əsas yollarından biridir. Abstrakt property deyir: "Qoy övladlar özləri qərar versinlər, bu property-nin dəyərini haradan alsınlar (və bəlkə də necə təyin etsinlər)".

Nümunə:
Fiqur üçün Name property-sini əlavə edək — bu hər bir övlad class-da olmalıdır, amma hər kəs özü qərar versin, orada nə qaytarsın.


public abstract class Shape
{
    public abstract string Name { get; }

    public abstract double CalculateArea();
}

İndi hər bir övlad bu property-ni implementasiya etməlidir:


public class Rectangle : Shape
{
    public double Width { get; }
    public double Height { get; }
    public override string Name => "Düzbucaqlı";

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public override double CalculateArea()
    {
        return Width * Height;
    }
}

public class Circle : Shape
{
    public double Radius { get; }
    public override string Name => "Dairə";

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}

Sintaksisin xüsusiyyətləri

Abstrakt property interface-dəki kimi görünür: o, bədən-implementasiya olmadan elan olunur, amma göstərilir ki, yalnız getter olacaq, yoxsa həm də setter.


public abstract class Creature
{
    // yalnız oxunan property
    public abstract string Species { get; }

    // oxunan və yazılan property
    public abstract int Age { get; set; }
}

Implementasiya edən class-da dəyərin alınması (və lazım olsa dəyişdirilməsi) üçün məntiq təyin etmək olar.

Abstrakt property-lər nə üçün lazımdır

Abstrakt property — əla alətdir, əgər istəyirsənsə ki, hər bir övlad özü qərar versin, necə dəyəri alsın və ya saxlasın. Bu tez-tez modelləşdirmədə, biznes modellərlə, view-modellərlə işləyərkən və ümumiyyətlə, property ilə işləmək məntiqi sadəcə sahənin qaytarılmasından daha mürəkkəb olanda lazımdır.

Məsələn, əgər bir fiqurun adı formul ilə hesablanır, digərində isə sabit qaytarılırsa, bütün bunları gözəl şəkildə abstrakt property arxasında "gizlətmək" olar.

3. Sxem: abstrakt class, metod və property-lər necə əlaqəlidir

Gəlin aşağıdakı sxemə baxaq ki, bu necə işləyir:


┌─────────────┐
│ abstract    │
│   Shape     │
│-------------│
│ +Name: str  │  <-- abstrakt property
│ +Area(): dbl│  <-- abstrakt metod
└─────┬───────┘
      │
 ┌────▼────┐      ┌───────┐
 │Rectangle│      │ Circle│
 │........ │ .... │ ......│
 │+Name    │      │+Name  │
 │+Area()  │      │+Area()│
 └─────────┘      └───────┘

Beləliklə, biz Shape class-ının istənilən övladı ilə işləmək üçün BİR interfeys təmin edirik, amma hər bir övlad "kapotun altında" istədiyini edə bilər.

Abstrakt metod və property üçün UML-diagram:


┌────────────────────────────┐
│        abstract class      │
│           Animal           │
│────────────────────────────│
│+ Name: string {abstract}   │
│+ MakeSound(): void {abstract}│
└─────────────┬──────────────┘
              │
     ┌────────┴──────────┐
     │                   │
┌────────────┐     ┌─────────────┐
│    Cat     │     │    Dog      │
│────────────│     │─────────────│
│+ Name      │     │+ Name       │
│+ MakeSound()│    │+ MakeSound()│
└────────────┘     └─────────────┘

4. Praktik ssenarilər və real layihələr üçün faydası

Abstrakt metodlar və property-lər — əgər sən inkişaf etməli olan class iyerarxiyaları dizayn edirsənsə, sənin alətindir. Bu böyük biznes tətbiqləri, çoxsəviyyəli predmeti sahə modelləri, plugin-sistemlər, UI-framework-lar üçün fundamentdir, harada ki, sistemin əsasları üçün "qanun" qoyulur və bütün övladlar üçün məcburidir.

Real layihələrdə belə "təmiz" arxitektur həllər aylar və illər sonra yeni obyektlər və funksiyalar əlavə etməyə imkan verir, bilə-bilə ki, köhnə kod artıq bütün davranış variantlarını nəzərə alır.

"Niyə" sualı və polimorfizmə qayıdış

Polimorfizm magiya kimi görünür, amma əslində bu sadəcə kontraktdır: "istənilən ailənin obyektində müəyyən metodu çağıra bilərsən və həmişə uyğun nəticə alacaqsan". Abstrakt metodlar və property-lər — bütün iyerarxiyanı ümumi dilə məcbur etmək üsuludur, amma "default" implementasiya olmadan.

Belə yanaşma plugin sistemlərində (IDE, qrafik redaktorlar, CRM-sistemlər) aktiv istifadə olunur, harada ki, üçüncü tərəf developer-lər öz genişlənmələrini yaradırlar, amma platformanın tələb etdiyi minimal funksiyaları implementasiya etməyə məcburdurlar. Məsələn, əgər sən faylların işlənməsi üçün modul yazırsansa, əsas class-da abstrakt property FileExtension və abstrakt metod Open() ola bilər ki, istənilən plugin öz tipinin fayllarını düzgün işləyə bilsin.

Abstrakt, virtual və adi class üzvləri arasındakı fərqlər

Xüsusiyyət Adi metod/property virtual abstract
Implementasiya var Var Var Yox
Override məcburidir Yox Yox (istəsən override edə bilərsən) Bəli (övlad class-da məcburidir)
Birbaşa çağırmaq olar Bəli Bəli Yox
Adi class-da ola bilər Bəli Bəli Yox
sealed kimi işarələmək olar Yox Bəli Yox

5. Bizim tədris tətbiqimizdə tətbiqi

İndi, yeni biliklərlə silahlanıb, gəlin fiqurlarla tətbiqimizə qayıdaq və baxaq, abstrakt property-lər və metodlar birlikdə necə işləyir ki, çevik və başadüşülən sistem yaratsın.


// Məsələn, proqramın əsas metodunda
List<Shape> shapes = new List<Shape>
{
    new Rectangle(4, 5),
    new Circle(2.5)
};

foreach (Shape shape in shapes)
{
    // Abstrakt Name property-si və CalculateArea metodu sayəsində,
    // biz fiqurun konkret tipini düşünmürük
    Console.WriteLine($"{shape.Name}, Sahə: {shape.CalculateArea():F2}");
}

Nəticə:

Düzbucaqlı, Sahə: 20.00
Dairə, Sahə: 19.63

Gözəllik: kod bilmir və düşünmür ki, fiqur kimdir — sadəcə lazım olan property və metodları çağırır, .NET CLR isə düzgün implementasiya ilə məşğul olur!

6. Tez-tez buraxılan səhvlər və implementasiya xüsusiyyətləri

Səhv №1: valideynin abstrakt metodu implementasiya olunmayıb.
Əgər törəmə class-da heç olmasa bir abstrakt metod və ya property implementasiya olunmayıbsa və class özü abstract kimi işarələnməyibsə, compiler layihəni yığmağa imkan verməyəcək. Bu faydalı qoruma mexanizmidir: "dəlikli" məntiqi olan obyekt yarada bilməyəcəksən — məsələn, CalculateArea() metodu olmayan fiqur.

Səhv №2: metod abstract kimi elan olunub, amma class yox.
Belə kod da compile olunmur. Əgər class-a abstract-metod əlavə etmisənsə, deməli, class özü də abstrakt olmalıdır:


public abstract class Polygon : Shape
{
    // CalculateArea() implementasiya olunmur, class abstrakt qalır
}

Səhv №3: abstrakt metodu virtual ilə implementasiya etməyə cəhd.
Abstrakt metod override açar sözü ilə implementasiya olunmalıdır, virtual ilə yox. Amma əgər istəyirsənsə ki, implementasiyanı iyerarxiyada daha aşağıda yenidən override etmək mümkün olsun, əvvəlcə metodu override edə bilərsən, sonra isə onu törəmə class-da virtual kimi elan edə bilərsən:


public override double CalculateArea()
{
    // Default implementasiya...
}

Daha dərin övlad class-da belə metodu yenidən override etmək olar. Amma onu yenidən abstract etmək olmaz, çünki artıq implementasiya var.

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