CodeGym /Kurslar /JAVA 25 SELF /Polimorfizmin praktik istifadəsi

Polimorfizmin praktik istifadəsi

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

1. Kolleksiyalarda polimorfizm: nə üçün lazımdır?

Gəlin bir sualla başlayaq: “Ümumiyyətlə, real proqramlarda polimorfizm nəyə lazımdır?”

Zoopark təsəvvür edin. Sizin baza sinfiniz Animal var, üstəlik bir sıra törəmələr: Dog, Cat, Cow, Parrot və hətta Platypus (ekzotika həvəskarları üçün ornitorinq). Onların hər biri səs çıxarmağı bacarır (makeSound()), amma bunu özünəməxsus şəkildə edir.

Hər heyvan üçün ayrıca massivlər yaratmaq əvəzinə, Animal tipli massiv və ya siyahı elan edir və ora istənilənini qoyursunuz:

Animal[] animals = {
    new Dog(),
    new Cat(),
    new Cow(),
    new Parrot()
};

İndi bu massiv üzrə dövr edib hər biri üçün makeSound() çağırmaq olar:

for (Animal animal : animals) {
    animal.makeSound();
}

Sehr! Hər obyekt hansı səsi çıxarmalı olduğunu özü bilir və sizə çoxlu if-lər və ya switch-lər yazmaq lazım deyil.

Bənzətmə ilə nümunə

Sanki heyvanlar qrupuna “Səs!” əmri verirsiniz və hərəsi özü qərar verir: it hürür, pişik miyoldayır, inək — mökür. Kimin kim olduğunu dəqiqləşdirmirsiniz — sadəcə eyni metodu çağırırsınız.

2. Praktiki nümunə: əməkdaşlar ierarxiyası

Gəlin nümunəni həyata (və gələcək IT işinizə) yaxınlaşdıraq. Təsəvvür edin ki, müxtəlif əməkdaşları olan şirkətimiz var: menecerlər, proqramçılar, testçilər. Hər birinin work() metodu var, amma o, fərqli-fərqli icra olunur.

Baza sinfinin elan edilməsi

public class Employee {
    public void work() {
        System.out.println("Əməkdaş işləyir...");
    }
}

Alt siniflər

public class Manager extends Employee {
    @Override
    public void work() {
        System.out.println("Menecer iclas keçirir.");
    }
}

public class Developer extends Employee {
    @Override
    public void work() {
        System.out.println("Proqramçı kod yazır.");
    }
}

public class Tester extends Employee {
    @Override
    public void work() {
        System.out.println("Testçi xətaları axtarır.");
    }
}

Baza tipli massiv/siyahının istifadəsi

public class CompanyDemo {
    public static void main(String[] args) {
        Employee[] team = {
            new Manager(),
            new Developer(),
            new Tester(),
            new Developer()
        };

        for (Employee e : team) {
            e.work(); // Hər obyekt üçün metodun "doğru" versiyası çağırılacaq
        }
    }
}

İcra nəticəsi:

Menecer iclas keçirir.
Proqramçı kod yazır.
Testçi xətaları axtarır.
Proqramçı kod yazır.

Üstünlüklər nələrdir?

  • “Əgər bu Developer-dirsə — filanı et” tipli çoxlu yoxlamalar yazmırsınız.
  • Yeni əməkdaş əlavə etmək (məsələn, Designer) — sadəcə yeni sinif yaratmaq və onu massivə əlavə etməkdir.
  • Əməkdaşlar massivindən istifadə edən kod ümumiyyətlə dəyişmir!

3. Polimorfizmin üstünlükləri: çeviklik və genişləndirilə bilənlik

Təsəvvür edək ki, şirkətinizdə yeni tip əməkdaş — Designer meydana çıxdı. Sizə lazım olan tək şey — yeni sinif yaratmaqdır:

public class Designer extends Employee {
    @Override
    public void work() {
        System.out.println("Dizayner maketlər hazırlayır.");
    }
}

İndi dizayneri komandaya əlavə etmək olar:

Employee[] team = {
    new Manager(),
    new Developer(),
    new Tester(),
    new Designer()
};

Vuala! Proqram dərhal yeni əməkdaş tipi ilə düzgün işləyir və massivi gəzib work() çağıran kodda bir sətir belə dəyişmir.

Bu da genişləndirilə bilənlik deməkdir: kodunuz yeni obyekt tiplərinə asanlıqla uyğunlaşır.

4. Polimorfizmin məhdudiyyətləri: medalın digər tərəfi

Təəssüf ki, hər sehrin öz məhdudiyyətləri var (və hər RPG-də olduğu kimi bunun da bir qiyməti var).

Yalnız baza sinfinin metodları əlçatandır

Employee tipli dəyişənlə işləyərkən yalnız Employee sinfində elan edilmiş metodları çağıra bilərsiniz. Əgər Developer sinfində xüsusi writeCode() metodu varsa, onu birbaşa çağıra bilməyəcəksiniz:

Employee e = new Developer();
// e.writeCode(); // Tərtib xətası: belə bir metod Employee-də yoxdur!

Çox istəyirsinizsə, spesifik metodu çağırmaq üçün tip çevirməsi etməli olacaqsınız. Amma bu, ən son çarədir. Əgər tez-tez tipləri çevirirsinizsə, bəlkə də siniflərin layihələndirilməsini yenidən gözdən keçirməyə dəyər — baza sinfi və ya interfeys lazımi metodu ehtiva etməlidir.

if (e instanceof Developer) {
    Developer dev = (Developer) e;
    dev.writeCode();
}

Ancaq onda bu yanaşmanın naminə qurduğumuz universallıq və zərifliyi itiririk. Buna görə baza sinfini elə layihələndirməyə çalışın ki, orada həqiqətən bütün törəmələrə lazım olan metodlar olsun.

5. Təcrübə: əməkdaşlar ierarxiyasını reallaşdıraq

Gəlin xoşu faydalı ilə birləşdirək: bir neçə tip əməkdaşın olduğu sadə tətbiq yazaq və onları emal etmək üçün polimorfizmdən istifadə edək.

Addım 1: Baza sinfi və alt siniflər

// Employee.java
public class Employee {
    public void work() {
        System.out.println("Əməkdaş işləyir...");
    }
}

// Manager.java
public class Manager extends Employee {
    @Override
    public void work() {
        System.out.println("Menecer iclas keçirir.");
    }
}

// Developer.java
public class Developer extends Employee {
    @Override
    public void work() {
        System.out.println("Proqramçı kod yazır.");
    }
}

// Tester.java
public class Tester extends Employee {
    @Override
    public void work() {
        System.out.println("Testçi xətaları axtarır.");
    }
}

Addım 2: Əsas sinif

// CompanyDemo.java
public class CompanyDemo {
    public static void main(String[] args) {
        Employee[] team = {
            new Manager(),
            new Developer(),
            new Tester(),
            new Developer()
        };

        for (Employee e : team) {
            e.work();
        }
    }
}

Addım 3: Genişləndirilə bilənliyi əlavə edək

Tutaq ki, bir aydan sonra şirkətdə yeni əməkdaş — dizayner peyda oldu. Lazım olan tək şey:

public class Designer extends Employee {
    @Override
    public void work() {
        System.out.println("Dizayner maketlər hazırlayır.");
    }
}

Bu qədər, indi dizayneri komandaya əlavə etmək olar:

Employee[] team = {
    new Manager(),
    new Developer(),
    new Tester(),
    new Designer()
};

Nəticə

Bütün əsas kod (CompanyDemo) dəyişməz qaldı! Bu, polimorfizmin gücüdür.

6. Polimorfizmdən istifadə zamanı tipik səhvlər

Səhv №1: Baza tipli istinad vasitəsilə spesifik metodlara çıxış gözləmək.
Çox vaxt yeni başlayanlar super sinif tipli dəyişən vasitəsilə alt sinfin spesifik metodlarını çağırmağa çalışırlar. Məsələn:

Employee e = new Developer();
// e.writeCode(); // Xəta! Belə metod Employee-də müəyyənləşdirilməyib.

Spesifik metodu çağırmaq üçün tipi çevirmək lazım gəlir, lakin onda universallıq itir.

Səhv №2: @Override annotasiyasından istifadə etməmək.
Annotasiyanı unutduqda, təsadüfən adında səhv edərək (məsələn) yeni metod yaza bilərsiniz. Bu halda polimorfizm sadəcə işləməyəcək və super sinifdəki versiya çağırılacaq.

Səhv №3: Ümumi interfeysin olmaması.
Əgər baza sinfi lazımi metodu ehtiva etmirsə, polimorfizm mümkün deyil. Məsələn, Employee-də work() metodu yoxdursa, əməkdaşlar massivi üzrə dövr həmin metodu hamı üçün çağıra bilməyəcək.

Səhv №4: Açıq/Qapalı prinsipinin pozulması.
Yeni əməkdaş tipini əlavə etmək üçün massivi/siyahını gəzən kodu dəyişməli olursunuzsa — deməli, polimorfizmdən düzgün istifadə etmirsiniz.

1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Rəqəmsal heyvan ensiklopediyasının səsləri
Rəqəmsal heyvan ensiklopediyasının səsləri
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Korporativ simfoniya: İşçilərin işində polimorfizm
Korporativ simfoniya: İşçilərin işində polimorfizm
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Komandanın genişləndirilməsi: Yeni işçi növünün əlavə olunması
Komandanın genişləndirilməsi: Yeni işçi növünün əlavə olunması
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Dinamik ofis: Polimorfizmin genişlənə bilməsi və çoxistifadəliliyi
Dinamik ofis: Polimorfizmin genişlənə bilməsi və çoxistifadəliliyi
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION