13. Inheritance

Oldingi boblarda class va object bilan ishlashni o‘rgandik.

Ba'zan bir class boshqa classdagi ma'lumot va methodlardan foydalanishi kerak bo‘ladi.

Masalan, Dog va Cat hayvon hisoblanadi.

Ularning ikkalasida ham:

ism
yosh

kabi ma'lumotlar bo‘lishi mumkin.

Bunday holatda umumiy class yaratib, boshqa classlar undan foydalanishi mumkin.

Java'da bu inheritance, ya'ni meros olish deyiladi.

Inheritance nima?

Inheritance — bir class boshqa classning field va methodlaridan foydalanishi.

Masalan:

Animal
   ↓
Dog

Bu yerda Dog Animaldan meros oladi.

Animal — parent class.

Dog — child class.


Parent class

Avval umumiy Animal classini yaratamiz.

class Animal {

    String ism;

    void ovqatlan() {
        System.out.println("Hayvon ovqatlanyapti.");
    }
}

Bu classda hayvon uchun umumiy ma'lumot va method bor.


Child class

Endi Dog classini yaratamiz.

class Dog extends Animal {

    void hur() {
        System.out.println("Vov-vov!");
    }
}

Bu yerda:

extends Animal

Dog Animaldan meros olayotganini bildiradi.


Object yaratish

Endi:

Dog it = new Dog();

Dog objecti Animaldagi methoddan ham foydalanishi mumkin.

it.ovqatlan();

Natija:

Hayvon ovqatlanyapti.

Shuningdek, Dogning o‘z methodi ham bor:

it.hur();

Natija:

Vov-vov!

To‘liq misol

class Animal {

    String ism;

    void ovqatlan() {
        System.out.println("Hayvon ovqatlanyapti.");
    }
}

class Dog extends Animal {

    void hur() {
        System.out.println("Vov-vov!");
    }
}

public class Main {

    public static void main(String[] args) {

        Dog it = new Dog();

        it.ism = "Bobik";

        System.out.println(it.ism);

        it.ovqatlan();
        it.hur();
    }
}

Natija:

Bobik
Hayvon ovqatlanyapti.
Vov-vov!

Dog o‘zida ism va ovqatlan() yaratmagan bo‘lsa ham, Animaldan meros olgani uchun ulardan foydalana oldi.


Nima uchun inheritance kerak?

Inheritance kodni qayta-qayta yozmaslikka yordam beradi.

Masalan, bizda:

Dog
Cat
Horse

classlari bor.

Ularning hammasida:

ism
yosh
ovqatlan()

bo‘lsa, bularni har bir classda qayta yozish shart emas.

Buning o‘rniga:

Animal

classini yaratamiz.

Keyin:

Dog extends Animal
Cat extends Animal
Horse extends Animal

deb yozamiz.


Yana bir misol

class Animal {

    void ovqatlan() {
        System.out.println("Ovqatlanyapti.");
    }
}

class Cat extends Animal {

    void miyovla() {
        System.out.println("Miyov!");
    }
}

Endi:

Cat mushuk = new Cat();

mushuk.ovqatlan();
mushuk.miyovla();

Natija:

Ovqatlanyapti.
Miyov!

Parent va Child

Inheritance'da ikkita muhim tushuncha bor.

Parent class — boshqa classga meros beradi.

Child class — parent classdan meros oladi.

Masalan:

class Animal {
}

class Dog extends Animal {
}

Bu yerda:

Animal → Parent
Dog    → Child

Child class o‘z methodiga ega bo‘lishi mumkin

Child class faqat parent classdagi methodlar bilan cheklanmaydi.

U o‘zining yangi methodlarini ham yaratishi mumkin.

class Animal {

    void ovqatlan() {
        System.out.println("Ovqatlanyapti.");
    }
}

class Dog extends Animal {

    void hur() {
        System.out.println("Vov-vov!");
    }
}

Dog quyidagilarga ega:

ovqatlan()
hur()

Fieldlar ham meros olinadi

Parent classda field bo‘lsa, child class undan foydalanishi mumkin.

class Person {

    String ism;
}

class Student extends Person {

    int ball;
}

Endi:

Student talaba = new Student();

talaba.ism = "Ali";
talaba.ball = 90;

Bu yerda ism Persondan meros olingan.

ball esa Studentning o‘z fieldi.


Constructor va inheritance

Parent classda constructor bo‘lishi mumkin.

Masalan:

class Person {

    String ism;

    Person(String ism) {
        this.ism = ism;
    }
}

Child classda esa parent constructorini super() orqali chaqirish mumkin.

class Student extends Person {

    int ball;

    Student(String ism, int ball) {
        super(ism);
        this.ball = ball;
    }
}

Object:

Student talaba = new Student("Ali", 90);

Bu yerda:

super(ism);

Person classining constructorini chaqiradi.

Hozircha superning asosiy vazifasini bilish kifoya.


super

super parent classga murojaat qilish uchun ishlatiladi.

Masalan:

class Animal {

    void ovoz() {
        System.out.println("Hayvon ovoz chiqaryapti.");
    }
}

class Dog extends Animal {

    void ovoz() {
        super.ovoz();

        System.out.println("Vov-vov!");
    }
}

Bu yerda:

super.ovoz();

parent classdagi ovoz() methodini chaqiradi.


Methodni o‘zgartirish

Child class parent classdagi methodni o‘ziga moslab qayta yozishi mumkin.

Masalan:

class Animal {

    void ovoz() {
        System.out.println("Hayvon ovoz chiqaryapti.");
    }
}

class Dog extends Animal {

    @Override
    void ovoz() {
        System.out.println("Vov-vov!");
    }
}

Endi:

Dog it = new Dog();

it.ovoz();

Natija:

Vov-vov!

Bu method overriding deyiladi.


@Override

@Override Java'ga bu method parent classdagi methodni qayta yozayotganini bildiradi.

Masalan:

@Override
void ovoz() {
    System.out.println("Vov-vov!");
}

Bu annotation xatolarni topishda ham yordam beradi.


Real hayotdagi misol

Masalan, universitetda turli odamlar bor:

Person
   ↓
Student

Person
   ↓
Teacher

Person classida:

ism
yosh

bo‘lishi mumkin.

Studentda:

ball

bo‘lishi mumkin.

Teacherda:

fan

bo‘lishi mumkin.

Shunday qilib umumiy ma'lumotlarni Personda saqlaymiz.


Inheritance qachon foydali?

Inheritance quyidagi holatlarda foydali:

  • Bir nechta classda umumiy kod bo‘lsa.
  • Classlar o‘rtasida aniq bog‘liqlik bo‘lsa.
  • Umumiy field va methodlarni bitta parent classga chiqarish kerak bo‘lsa.

Masalan:

Animal
Dog
Cat

Bu yaxshi inheritance misoli.


Amaliy mashqlar

1-mashq

Animal classini yarating.

Unda:

ovqatlan()

methodi bo‘lsin.

Keyin Dog classini Animaldan meros oldiring.

2-mashq

Dog classiga:

hur()

methodini qo‘shing.

3-mashq

Person classini yarating.

Unda:

ism
yosh

bo‘lsin.

Keyin Student classini Persondan meros oldiring.

Studentga:

ball

fieldini qo‘shing.

4-mashq

Animal classida:

ovoz()

methodini yarating.

Keyin Dog classida uni @Override yordamida o‘zgartiring.

5-mashq

Quyidagi tuzilmani yarating:

Vehicle
   ↓
Car

Vehicleda:

yur()

methodi bo‘lsin.

Carda esa:

signal()

methodi bo‘lsin.


Muhim narsalarni eslab qoling

Inheritance — bir classning boshqa classdan meros olishi.

Meros olish uchun:

extends

ishlatiladi.

Masalan:

class Dog extends Animal {
}

Animal — parent class.

Dog — child class.

super — parent classga murojaat qilish uchun ishlatiladi.

@Override — parent classdagi methodni qayta yozish uchun ishlatiladi.

Inheritance kodni qayta ishlatishga va classlarni tartibli tashkil qilishga yordam beradi.