12. Encapsulation

Oldingi boblarda class va object bilan ishlashni o‘rgandik.

Masalan:

class Student {
    String ism;
    int yosh;
}

Bu kodda ism va yosh ga tashqaridan to‘g‘ridan-to‘g‘ri murojaat qilish mumkin.

Lekin katta dasturlarda ma'lumotlarni to‘g‘ridan-to‘g‘ri o‘zgartirish har doim ham yaxshi emas.

Buning uchun encapsulation ishlatiladi.

Encapsulation nima?

Encapsulation — class ichidagi ma'lumotlarni yashirish va ularga nazorat orqali murojaat qilish usuli.

Oddiy qilib:

Ma'lumotni yashiramiz va unga methodlar orqali murojaat qilamiz.

Muammo

Masalan:

class Student {
    String ism;
    int yosh;
}

Keyin:

Student talaba = new Student();

talaba.yosh = -100;

Bu kod ishlaydi.

Lekin -100 yosh bo‘lishi mantiqan noto‘g‘ri.

Demak, yosh qiymatini nazorat qilishimiz kerak.

private

Ma'lumotni tashqaridan to‘g‘ridan-to‘g‘ri o‘zgartirishni cheklash uchun private ishlatamiz.

class Student {
    private String ism;
    private int yosh;
}

Endi tashqaridan:

Student talaba = new Student();

talaba.yosh = 18;

deb yozib bo‘lmaydi.

Chunki yosh private.

Getter

private fieldning qiymatini olish uchun getter ishlatiladi.

Masalan:

class Student {

    private String ism;

    String getIsm() {
        return ism;
    }
}

Endi:

Student talaba = new Student();

System.out.println(talaba.getIsm());

Getter ism qiymatini qaytaradi.

Setter

private fieldga qiymat berish uchun setter ishlatiladi.

Masalan:

class Student {

    private String ism;

    void setIsm(String ism) {
        this.ism = ism;
    }

    String getIsm() {
        return ism;
    }
}

Endi:

Student talaba = new Student();

talaba.setIsm("Ali");

System.out.println(talaba.getIsm());

Natija:

Ali

Getter va setter bilan yosh

class Student {

    private int yosh;

    void setYosh(int yosh) {
        this.yosh = yosh;
    }

    int getYosh() {
        return yosh;
    }
}

Keyin:

Student talaba = new Student();

talaba.setYosh(18);

System.out.println(talaba.getYosh());

Natija:

18

Setter yordamida tekshirish

Encapsulationning katta foydasi — qiymatni tekshirish mumkin.

Masalan:

class Student {

    private int yosh;

    void setYosh(int yosh) {

        if (yosh >= 0) {
            this.yosh = yosh;
        }
    }

    int getYosh() {
        return yosh;
    }
}

Endi:

Student talaba = new Student();

talaba.setYosh(-10);

System.out.println(talaba.getYosh());

-10 qabul qilinmaydi.

Chunki setterda tekshiruv bor.

To‘liq misol

class Student {

    private String ism;
    private int yosh;

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

    String getIsm() {
        return ism;
    }

    void setIsm(String ism) {
        this.ism = ism;
    }

    int getYosh() {
        return yosh;
    }

    void setYosh(int yosh) {

        if (yosh >= 0) {
            this.yosh = yosh;
        }
    }
}

Keyin:

public class Main {

    public static void main(String[] args) {

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

        System.out.println(talaba.getIsm());
        System.out.println(talaba.getYosh());

        talaba.setYosh(19);

        System.out.println(talaba.getYosh());
    }
}

Natija:

Ali
18
19

Nima uchun getter va setter kerak?

Tasavvur qiling, bizda:

private int yosh;

bor.

Agar yosh private bo‘lsa, tashqaridan:

talaba.yosh = 18;

deb o‘zgartirib bo‘lmaydi.

Buning o‘rniga:

talaba.setYosh(18);

ishlatamiz.

Bu bizga qiymatni tekshirish imkonini beradi.

Har doim setter kerakmi?

Yo‘q.

Ba'zan qiymatni faqat o‘qish kerak bo‘ladi.

Masalan:

class Student {

    private String ism;

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

    String getIsm() {
        return ism;
    }
}

Bu classda setIsm() yo‘q.

Demak, tashqaridan ismni o‘qish mumkin, lekin o‘zgartirish mumkin emas.

Masalan:

System.out.println(talaba.getIsm());

ishlaydi.

Lekin:

talaba.setIsm("Vali");

ishlamaydi.

public va private

Hozircha ikkita access modifierni bilish kifoya:

public — boshqa joylardan foydalanish mumkin.

private — faqat class ichida foydalanish mumkin.

Masalan:

class Student {

    private String ism;

    public String getIsm() {
        return ism;
    }
}

Bu yerda ism yashirilgan.

Unga getIsm() orqali murojaat qilamiz.

Oddiy tasavvur

Encapsulationni uyga o‘xshatish mumkin.

Uy ichidagi barcha narsalarni ko‘chadan turib boshqarib bo‘lmaydi.

Masalan:

Uy ichidagi ma'lumot
        ↓
     private
        ↓
   maxsus method
        ↓
   getter / setter

Getter va setter ma'lumotlarga nazoratli kirish imkonini beradi.

Amaliy mashqlar

1-mashq

Person classini yarating.

Unda:

ism
yosh

private fieldlari bo‘lsin.

Getter va setter yarating.

2-mashq

yosh uchun setter yozing.

Agar yosh 0 dan kichik bo‘lsa, qiymatni qabul qilmasin.

3-mashq

BankAccount classini yarating.

Unda:

private double balans;

bo‘lsin.

Balansni olish uchun getter yarating.

4-mashq

BankAccount uchun pul qo‘shadigan method yarating:

pulQosh(double summa)

Agar summa 0 dan kichik bo‘lsa, qabul qilinmasin.

Muhim narsalarni eslab qoling

Encapsulation — ma'lumotlarni yashirish va ularga nazoratli murojaat qilish.

private — ma'lumotni class ichida yashiradi.

Getter — qiymatni olish uchun ishlatiladi.

getYosh()

Setter — qiymatni o‘zgartirish uchun ishlatiladi.

setYosh(18)

Encapsulation katta dasturlarda ma'lumotlarni tartibli va xavfsiz boshqarishga yordam beradi.