CodeGym /Kurslar /JAVA 25 SELF /Sinif iyerarxiyalarının yaradılması, həyatdan nümunələr

Sinif iyerarxiyalarının yaradılması, həyatdan nümunələr

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

1. Sinif iyerarxiyası nədir?

Proqramlaşdırmada (və yalnız onda deyil) iyerarxiya — yuxarıda «ümumi» obyektlərin (baza siniflərin), aşağıda isə daha konkretlərinin (alt siniflərin) olduğu ağacvari quruluşdur. Java-da sinif iyerarxiyası irsiyyət vasitəsilə qurulur: hər bir alt sinif özü də digər alt siniflər üçün valideyn ola bilər və s.

Analoqiya:

  • Heyvan (Animal) — ümumi sinifdir.
  • Məməli (Mammal) — heyvanın xüsusi halıdır.
  • İt (Dog) — məməlilərin xüsusi halıdır.
  • Və məsələn, konkret «Şarik» — artıq Dog sinfinin obyektidir.

Kodda bu belə görünür:

class Animal { }
class Mammal extends Animal { }
class Dog extends Mammal { }

Sinif iyerarxiyası «yuxarıda» ümumi xüsusiyyətləri və davranışı, «aşağıda» isə detalları təsvir etməyə imkan verir. Bu, kodu daha məntiqi edir və təkrarı aradan qaldırır.

İyerarxiya sxemi

Animal
├── Mammal
│   ├── Dog
│   └── Cat
└── Bird
    └── Sparrow

2. İyerarxiyanı necə qurmalı: məntiq və praktika

Ümumi və xüsusini müəyyən edirik

Əsas qayda: baza sinfi bütün övladları üçün xarakterik olanı ehtiva etməlidir. Unikal olan hər şey — alt siniflərə keçir.

Nümunə:

  • Bütün heyvanlar nəfəs ala və yeyə bilir — deməli, breathe()eat() metodları Animal sinfində olmalıdır.
  • Yalnız quşlar uça bilir — deməli, fly() metodu Bird sinfində olacaq, Animal-da yox.
  • Yalnız itlər hürür — bark() metodu Dog sinfində olacaq.

Nümunə: Heyvanlar

// Baza sinif
class Animal {
    String name;

    Animal(String name) {
        this.name = name;
    }

    void eat() {
        System.out.println(name + " yeyir.");
    }

    void makeSound() {
        System.out.println(name + " səs çıxarır.");
    }
}

// Alt sinif: Məməli
class Mammal extends Animal {
    Mammal(String name) {
        super(name);
    }

    void feedMilk() {
        System.out.println(name + " balalarını südlə bəsləyir.");
    }
}

// Alt sinif: İt
class Dog extends Mammal {
    Dog(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " hürür: Hav-hav!");
    }

    void wagTail() {
        System.out.println(name + " quyruğunu yelləyir.");
    }
}

// Alt sinif: Pişik
class Cat extends Mammal {
    Cat(String name) {
        super(name);
    }

    @Override
    void makeSound() {
        System.out.println(name + " miyovlayır: Miyov!");
    }

    void purr() {
        System.out.println(name + " mırıldayır.");
    }
}

// Alt sinif: Quş
class Bird extends Animal {
    Bird(String name) {
        super(name);
    }

    void fly() {
        System.out.println(name + " uçur.");
    }

    @Override
    void makeSound() {
        System.out.println(name + " cikkildəyir: Cik-cik!");
    }
}

main-də çağırış:

public class ZooDemo {
    public static void main(String[] args) {
        Dog sharik = new Dog("Şarik");
        Cat murka = new Cat("Murka");
        Bird sparrow = new Bird("Sərçə");

        sharik.eat();        // Şarik yeyir.
        sharik.makeSound();  // Şarik hürür: Hav-hav!
        sharik.feedMilk();   // Şarik balalarını südlə bəsləyir.
        sharik.wagTail();    // Şarik quyruğunu yelləyir.

        murka.eat();         // Murka yeyir.
        murka.makeSound();   // Murka miyovlayır: Miyov!
        murka.feedMilk();    // Murka balalarını südlə bəsləyir.
        murka.purr();        // Murka mırıldayır.

        sparrow.eat();       // Sərçə yeyir.
        sparrow.makeSound(); // Sərçə cikkildəyir: Cik-cik!
        sparrow.fly();       // Sərçə uçur.
    }
}

Vizuallaşdırma: sinif ağacı

Sinif Valideyn sinif Xüsusiyyətlər
Animal
Object
name, eat(), makeSound()
Mammal
Animal
feedMilk()
Dog
Mammal
makeSound(), wagTail()
Cat
Mammal
makeSound(), purr()
Bird
Animal
fly(), makeSound()

3. Həyatdan digər nümunələr

Həndəsi fiqurlar

Sinif iyerarxiyaları həndəsi modelləşdirmə üçün çox uyğundur.

// Baza sinif
class Shape {
    void draw() {
        System.out.println("Fiqur çəkirik.");
    }
}

// Dairə
class Circle extends Shape {
    double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    @Override
    void draw() {
        System.out.println("Radiusu " + radius + " olan dairə çəkirik");
    }
}

// Düzbucaqlı
class Rectangle extends Shape {
    double width, height;

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    void draw() {
        System.out.println("Düzbucaqlı çəkirik " + width + "x" + height);
    }
}

İstifadə:

public class ShapeDemo {
    public static void main(String[] args) {
        Shape s1 = new Circle(5);
        Shape s2 = new Rectangle(3, 4);

        s1.draw(); // Radiusu 5.0 olan dairə çəkirik
        s2.draw(); // Düzbucaqlı çəkirik 3.0x4.0
    }
}

Nəqliyyat

class Vehicle {
    void move() {
        System.out.println("Nəqliyyat hərəkət edir.");
    }
}

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

class Bicycle extends Vehicle {
    @Override
    void move() {
        System.out.println("Velosipedçi pedalı fırladır.");
    }
}

main:

Vehicle v1 = new Car();
Vehicle v2 = new Bicycle();

v1.move(); // Maşın yolda gedir.
v2.move(); // Velosipedçi pedalı fırladır.

İstifadəçilər

class User {
    String username;
    User(String username) { this.username = username; }
    void login() { System.out.println(username + " sistemə daxil oldu."); }
}

class Admin extends User {
    Admin(String username) { super(username); }
    void deleteUser(String user) {
        System.out.println(username + " istifadəçini sildi " + user);
    }
}

class Customer extends User {
    Customer(String username) { super(username); }
    void buy() { System.out.println(username + " alış etdi."); }
}

4. Faydalı incəliklər

İrsiyyətdən sui-istifadə etməyin. İrsiyyət «is-a» münasibətləri üçün alətdir. Əgər demək istəyirsinizsə ki, «Pişik — Heyvandır», irsiyyətdən istifadə edin. Əgər «Pişiyin Quyruğu var» deməkdirsə, kompozisiyadan istifadə edin (has-a).

Pis:

class Engine { /* ... */ }
class Car extends Engine { /* Maşın — mühərrikdirmi? Xeyr, bu kompozisiyadır! */ }

Yaxşı:

class Car {
    Engine engine; // Maşının tərkibində mühərrik var
}

Çox dərin iyerarxiyalar qurmayın. Səviyyə çoxaldıqca kodu dəstəkləmək və anlamaq çətinləşir. Adətən 2–3 səviyyə — əksər tapşırıqlar üçün maksimumdur.

Çox «yastı» iyerarxiyalar da etməyin. Əgər 20 sinifiniz var və hamısı birbaşa bir baza sinfindən miras alırsa, ola bilsin, memarlığı yenidən nəzərdən keçirməyə dəyər.

«Rahatlıq» naminə irsiyyət. Bəzən metod və ya sahələri «oğurlamaq» istəyirik, məntiqi düşünmədən. Bu xaosa aparır! Əgər class Aclass B məntiqi olaraq əlaqəli deyilsə, class B-ni yalnız bir-iki metod üçün extends A etməyin.

Liskov əvəzləmə prinsipinin pozulması. Əgər alt sinif valideynin yerinə gözlənilməz problemlər olmadan istifadə oluna bilmirsə — iyerarxiya səhv qurulub.

Kodun təkrarlanması. Əgər «eyni metodu sinifdən sinfə köçürürəm» fikri sizə tanışdırsa, yəqin ki, onu baza sinfinə çıxarmağın vaxtıdır.

5. Sinif iyerarxiyalarını qurarkən tipik səhvlər

Səhv №1: «is-a» məntiqi olmadan irsiyyət.
Əgər irsiyyəti yalnız metod və ya sahələrə çıxış üçün, alt sinif həqiqətən də «valideynin növüdür» deyə bilmədən istifadə edirsinizsə, kodunuz tezliklə qarışıqlığa çevriləcək. Məsələn, «Maşın Mühərrikdən miras alır» — bu is-a deyil, has-a-dır.

Səhv №2: Alt sinfin unikal xüsusiyyətlərini nəzərə almamaq.
Əgər bütün alt sinifləriniz eyni görünür və heç nə əlavə etmir, bəlkə də iyerarxiya lazım deyil — bir sinifdən istifadə edin.

Səhv №3: Alt siniflərdə kodun təkrarlanması.
Eyni implementasiyanı bir neçə alt sinifdə kopyalayırınızsa, onu valideyn sinfinə çıxarmağa dəyər.

Səhv №4: Çox mürəkkəb və ya dərin iyerarxiya.
Çoxsəviyyəli iyerarxiyaları dəstəkləmək və test etmək çətindir. Nə qədər sadə — bir o qədər yaxşı!

Səhv №5: Metodların @Override annotasiyası olmadan yenidən təyini.
Annotasiyasız metod imzasında səhv etmək asandır və o zaman metod yenidən təyin olunmayacaq, yeni hesab ediləcək. Həmişə @Override-dan istifadə edin!

1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Virtual ev heyvanı: Bobik yeyir 🐕
Virtual ev heyvanı: Bobik yeyir 🐕
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Sürücülük məktəbi: Hərəkət və siqnallar 🚦
Sürücülük məktəbi: Hərəkət və siqnallar 🚦
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Məktəb ierarxiyası: Mən kiməm? 🎓
Məktəb ierarxiyası: Mən kiməm? 🎓
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Zooloji ensiklopediyası: Pişiklərin xüsusiyyətləri 🐈
Zooloji ensiklopediyası: Pişiklərin xüsusiyyətləri 🐈
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION