CodeGym /Kurslar /JAVA 25 SELF /OOP-də abstraksiya: nə üçün və necə tətbiq etmək

OOP-də abstraksiya: nə üçün və necə tətbiq etmək

JAVA 25 SELF
Səviyyə , Dərs
Mövcuddur

1. Abstraksiya anlayışı

Qısaca desək: abstraksiya — mürəkkəb şeylərə sadə baxmaq sənətidir.

Proqramlaşdırmada abstraksiya — obyektlər qrupunun ümumi xüsusiyyət və davranışlarını seçib ayırma prosesidir, bu zaman özəl detallar (məsələn, nəyinsə necə işləməsi «kapotun altında») nəzərə alınmır. Təsəvvür edin ki, şəhərin xəritəsini çəkirsiniz: orada yollar, binalar, çaylar qeyd olunur — amma hər pəncərədə pərdənin rəngi kimi təfərrüatlar yoxdur. Xəritə — şəhərin abstraksiyasıdır.

OOP-də abstraksiya — tapşırıq üçün vacib olan xüsusiyyət və hərəkətləri əks etdirən, lazımsız detallarını gizlədən sinif və interfeyslər yaratmaqdır.

Həyatdan nümunələr

  • Nəqliyyat — abstraksiyadır. Avtobus, velosiped və ya kosmik gəmi olması fərq etmir — əsas odur ki, nəqliyyatın ümumi cəhətləri var: hərəkət edə bilir, sərnişinləri və sürücüsü var.
  • Heyvan — həmçinin abstraksiyadır. Bütün heyvanlar nəfəs alır, yeyir, hərəkət edir — amma bunu necə etdikləri konkret növdən asılıdır.
  • Ödəniş — bank proqramlarında abstraksiyadır. Sizi həmişə maraqlandırmır ki, ödəniş kartladır, PayPal-la ya da bitkoinlədir — əsas odur ki, onu icra etmək və nəticə almaq mümkündür.

Niyə abstraksiya vacibdir?

  • Cari tapşırığın həlli üçün vacib olmayan detalları düşünməmək.
  • Sistemləri elə layihələndirmək ki, genişləndirmək və dəstəkləmək asan olsun.
  • Konkret reallaşdırmadan asılı olmayaraq, obyektlərlə ümumi interfeys vasitəsilə işləmək.

2. Java-da abstraksiya

Java-da abstraksiya iki əsas alətlə həyata keçirilir:

  1. Abstrakt siniflər (abstract class)
  2. İnterfeyslər (interface)

Bu mühazirədə diqqəti abstrakt siniflərə yönəldəcəyik. (İnterfeyslərə çox tez çatacağıq!)

Abstrakt sinif — birbaşa obyekt yaradılması üçün nəzərdə tutulmayan sinifdir. O, digər siniflər üçün ümumi baza (şablon) müəyyən edir. Abstrakt sinifdə həm həyata keçirilmiş metodlar (gövdəsi olan), həm də abstrakt metodlar (gövdəsiz) ola bilər — yəni mütləq törəmələrdə reallaşdırılmalı olanlar.

Abstrakt metod — reallaşdırması, yəni gövdəsi olmayan metoddur. O bunu bildirir: «Bu sinifin bütün törəmələri bu metodu öz qaydasınca reallaşdırmalıdır».

Nümunə: «Fiqur» abstraksiyası

public abstract class Shape {
    public abstract void draw(); // Abstrakt metod — gövdə yoxdur!
}

Burada belə deyirik: «Bütün fiqurlar çəkilə bilir, amma necə — bilmirəm; qoy hər törəmə özü qərar versin».

Niyə reallaşdırmanın detalları həmişə lazım deyil?

Abstraksiyadan istifadə edəndə obyektlə onun «üzü» — dəstəkləməli olduğu metodlar dəsti vasitəsilə işləyirsiniz. Bu metodun daxilən necə işləməsi vacib deyil.

Məsələn, bir obyektə payment.process() çağırışı edirsiniz ki, ödəniş icra olunsun. O necə reallaşdırılıb — fərq etməz; əsas odur işləsin. Bu imkan verir:

  • Bir reallaşdırmanı başqa ilə əvəz etməyə, onu istifadə edən kodu yenidən yazmadan.
  • Testləşdirməni sadələşdirməyə (reallaşdırmaları «stub»larla əvəz etmək olar).
  • Kodu daha çevik və dəyişikliklərə davamlı etməyə.

3. Abstraksiyanın üstünlükləri

Layihələndirməni və dəstəyi sadələşdirmə
Abstraksiya artıq şeylər haqqında düşünməməyə imkan verir. Avtomobilin mühərrikinin quruluşunu bilməyə ehtiyac yoxdur ki, onu idarə edəsiniz — sükan, pedallar və «irəli get» təlimatı kifayətdir. Koddakı kimi: əgər siz abstrakt sinif və ya interfeyslə işləyirsinizsə, yalnız sizə lazım olanı görürsünüz.

Sistemi genişləndirməyin asanlığı
Sisteminiz abstraksiyalara söykənirsə, yeni obyekt tiplərini asanlıqla əlavə edirsiniz. Məsələn, əgər sizdə Shape adlı abstrakt sinif varsa, köhnə kodu dəyişmədən yeni fiqur tipi — Triangle əlavə edə bilərsiniz.

Komponentlərin əlaqəliliyinin azaldılması
Əgər proqramın müxtəlif hissələri yalnız abstraksiyalar vasitəsilə ünsiyyət qurursa, onları bir-birindən asılı olmayaraq dəyişmək mümkündür. Bu, rozetka və fiş kimidir: əgər standart uyğun gəlirsə, istənilən cihazı rozetkaya qoşa bilərsiniz.

4. Praktiki nümunələr

Gəlin abstraksiyanın praktikada necə göründüyünə baxaq. Onları öz tədris tətbiqinizə daxil edib əl ilə yoxlaya biləsiniz deyə nümunələrdən istifadə edəcəyik.

Nümunə 1: «Shape» sinfi (Fiqur)

public abstract class Shape {
    public abstract void draw();
}

İndi bir neçə konkret fiqur yaradaq:

public class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("Dairə çəkirik");
    }
}

public class Rectangle extends Shape {
    @Override
    public void draw() {
        System.out.println("Düzbucaqlı çəkirik");
    }
}

Abstraksiyadan istifadə edək:

Shape s1 = new Circle();
Shape s2 = new Rectangle();

s1.draw(); // Dairə çəkirik
s2.draw(); // Düzbucaqlı çəkirik

Burada biz Shape tipli dəyişənlərlə işləyirik — və daxilində hansı fiqurun olması vacib deyil. Bu, abstraksiyanın gücüdür!

Nümunə 2: «Payment» sinfi

public abstract class Payment {
    public abstract void process();
}

Konkret reallaşdırmalar:

public class CreditCardPayment extends Payment {
    @Override
    public void process() {
        System.out.println("Kredit kartı ilə ödənişin emalı");
    }
}

public class PaypalPayment extends Payment {
    @Override
    public void process() {
        System.out.println("PayPal vasitəsilə ödənişin emalı");
    }
}

İstifadə:

Payment[] payments = {
    new CreditCardPayment(),
    new PaypalPayment()
};

for (Payment p : payments) {
    p.process();
}

Nəticədə hər bir ödəniş öz qaydasınca emal olunur, lakin onları çağıran kod bunu düşünmür.

5. Abstraksiya və reallaşdırma detallarının balansı: necə çaşmamaq

Abstraksiya “nədir”, “necə” deyil

Abstraksiya layihələndirəndə belə sualı cavablayırsınız: «Obyekt nəyi bacarmalıdır?»
Reallaşdırmanın detalları isə artıq «Bunu necə edir?» sualıdır.

Məsələn:

  • Abstraksiya: «İstənilən fiqur çəkilə bilməlidir (draw()).»
  • Reallaşdırma detalları: «Dairə çevrə ilə, düzbucaqlı — dörd xəttlə çəkilir.»

Həyatdan analoji nümunə

Televizor pultunu xatırlayın. Onun siqnalı necə ötürməsi sizi maraqlandırmır — əsas odur ki, «yandırmaq», «kanalı dəyişmək» və «səsi artırmaq» düymələri var. Bu, abstraksiyadır — basıb istifadə etdiyiniz düymələr toplusu. Amma pultu layihələndirən mühəndislər artıq reallaşdırma detallarını düşünməlidirlər.

6. Proqramda abstraksiyaları necə ayırmaq

Addım 1. Ümumi cəhətləri tapın

Predmet sahənizdəki obyektlərə baxın. Onların nəsi ortaqdır? Məsələn, bütün nəqliyyat vasitələri gedə bilir, bütün heyvanlar yeyə bilir, bütün ödənişləri icra etmək olar.

Addım 2. Abstrakt sinifi müəyyən edin

Bütün obyektlər üçün yalnız ümumi olanı ehtiva edən abstrakt sinif yaradın.

public abstract class Transport {
    public abstract void move();
}

Addım 3. Detalları alt siniflərdə reallaşdırın

public class Car extends Transport {
    @Override
    public void move() {
        System.out.println("Maşın yolda gedir");
    }
}

public class Bicycle extends Transport {
    @Override
    public void move() {
        System.out.println("Velosiped pedalları fırladır");
    }
}

Addım 4. Kodda abstraksiyadan istifadə edin

Transport[] transports = {
    new Car(),
    new Bicycle()
};

for (Transport t : transports) {
    t.move();
}

Kodunuz abstraksiyalarla işləyir — və reallaşdırma detallarından asılı deyil.

7. Abstraksiya və detallılıq: balans

Tipik başlanğıc səhvi — abstraksiyanı ya həddən artıq detallı, ya da əksinə, həddən artıq ümumi etmək.

  • Əgər abstraksiya həddən artıq ümumidirsə (məsələn, «Object» sinfi «doSomething» metodu ilə), ondan heç bir fayda yoxdur.
  • Əgər abstraksiya həddən artıq detallıdırsa (məsələn, «qırmızı haşiyəli və radiusu 5 olan dairə»), o, mənasını itirir — birbaşa konkret sinfi yazmaq daha asandır.

Qızıl qayda: abstraksiya yalnız həqiqətən ümumi və tapşırığınız üçün vacib olanı əks etdirməlidir.

8. Abstraksiya ilə işləyərkən tipik səhvlər

Səhv №1: abstrakt sinifin obyektini yaratmağa cəhd.
Abstrakt siniflər birbaşa obyekt yaratmaq üçün nəzərdə tutulmayıb. Əgər Shape s = new Shape(); yazmağa çalışsanız, kompilyator belə bir səhv verəcək: Cannot instantiate the type Shape. Bu, mağazada sadəcə «nəqliyyat» almağa cəhddən fərqsizdir. Alınmayacaq: konkret velosiped, maşın və ya avtobus seçməlisiniz.

Səhv №2: törəmədə abstrakt metodu reallaşdırmağı unutmaq.
Əgər sinif abstrakt sinifi miras alır, amma onun bütün abstrakt metodlarını reallaşdırmırsa, o da abstrakt olur — və ondan obyekt yaradıla bilməz. Bütün məcburi metodları reallaşdırdığınıza əmin olun.

Səhv №3: abstraksiya ilə reallaşdırma detallarını qarışdırmaq.
Əgər abstrakt sinifə yalnız bir alt sinifə lazım olan detallar əlavə etməyə başlayırsınızsa — bu, pis abstraksiyanın əlamətidir. Məsələn, əgər Payment abstrakt sinfində cardNumber sahəsi peyda olursa, halbuki bütün ödənişlər kartla edilmir.

Səhv №4: abstraksiyalara həddindən artıq aludə olmaq.
Abstraksiyanı abstraksiya xatirinə etmək lazım deyil. Sistemdə cəmi bir obyekt tipi varsa və heç vaxt genişlənməyəcəksə, abstraksiya kodu yalnız mürəkkəbləşdirəcək.

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