CodeGym /Kurslar /JAVA 25 SELF /Giriş modifikatorları ilə bağlı səhvlər

Giriş modifikatorları ilə bağlı səhvlər

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

1. Giriş

Java-da giriş modifikatorları — evdəki kilid sistemi kimidir. Onlar kimin və haradan sizin otağınıza (və ya sinfinizin sahə/metoduna) “daxil ola” biləcəyini müəyyənləşdirir. Əgər bütün qapılar açıqdırsa — istənilən kəs gəlib nəsə dəyişə bilər. Əgər hər şey bağlıdırsa — heç kim heç nə poza bilməz, amma elə də ola bilər ki, bir anda siz özünüz kiliddə qalasınız.

Xatırladaq ki, Java-da dörd əsas giriş səviyyəsi var:

Modifikator Sinif daxilində əlçatandır Paket daxilində əlçatandır Alt siniflərdə əlçatandır Digər paketlərdə əlçatandır
private
✔
(package) ✔ ✔
protected
✔ ✔ ✔ (mirasalma vasitəsilə)
public
✔ ✔ ✔ ✔

(package) — modifikator açıq şəkildə göstərilmədikdə. Belə sinif üzvü yalnız bir paket daxilində görünür.

2. Giriş modifikatorları ilə bağlı tipik səhvlər

Səhv 1: Susmaya görə modifikatorlu sahələr və metodlar (package-private)

Yeni başlayanların ən çox etdiyi səhv — giriş modifikatorunu göstərməyi unutmaqdır. Nəticədə sahə və ya metod bütün paketdə əlçatan olur, halbuki bunu planlaşdırmamışdınız. Bu o vaxta gətirib çıxara bilər ki, (eyni paketdə olan, amma sizinlə bağlı olmayan) başqa sinif obyektinizin daxili vəziyyətini dəyişə bilsin.

// Səhv: name sahəsi qorunmur!
class User {
    String name; // package-private!
}

Nəticədə bu paketdəki istənilən sinif belə yaza bilər:

User user = new User();
user.name = "Vasya"; // məhdudiyyətsiz!

Səhv 2: İnkapsulyasiyanın pozulması — açıq sahələr (public)

İkinci ən yayğın səhv — sinif sahələrini public elan etməkdir. Bu, siz yeni öyrənəndə və ya qısa nümunə yazanda rahat görünə bilər, amma real layihələrdə bu demək olar ki, həmişə pisdir. Məlumatlarınızın kim və necə dəyişməsinə nəzarəti itirirsiniz.

public class Account {
    public double balance; // Təhlükəli!
}

İndi istənilən kod aşağıdakı kimi edə bilər:

Account acc = new Account();
acc.balance = -1000000; // Bəs indi günahkar kimdir?

Səhv 3: Getter və setter-lərin olmaması

Bəzən tərtibatçı sahələri private edir, lakin onları idarə etmək üçün metodları əlavə etməyi unudur. Nəticədə dəyəri əldə etmək və ya dəyişmək mümkün olmur — halbuki bəzi hallarda bu uyğun olardı.

public class Product {
    private String name;
    // Nə getName(), nə də setName() var
}

Səhv 4: Başqa sinifdən private-üzvlərə müraciət cəhdi

Əgər sahəni və ya metodu private kimi elan etmisinizsə, ona başqa sinifdən müraciət etmək olmaz, hətta həmin sinif eyni paketdə olsa belə. Yeni başlayanlar tez-tez niyə sahənin “görünmədiyinə” təəccüblənirlər.

public class User {
    private String password;
}

public class UserService {
    public void resetPassword(User user) {
        // user.password = "123"; // Kompilyasiya xətası!
    }
}

Səhv 5: protected ilə bağlı səhvlər

Bir çoxları protected-in “harada mirasalma varsa, hər yerdə görünür” demək olduğunu hesab edir. Amma Java-da paketdən kənarda protected-üzvlərə giriş yalnız mirasalma vasitəsilə və yalnız alt sinif üçün mümkündür. Bu, asanlıqla gözdən qaçan bir incəlikdir.

package animals;

public class Animal {
    protected void sleep() {}
}

package zoo;
import animals.Animal;

public class Dog extends Animal {
    public void test() {
        sleep(); // OK — varis
    }
}

public class NotADog {
    public void test() {
        Animal a = new Animal();
        // a.sleep(); // Xəta: varis deyil!
    }
}

3. Necə düzgün: ən yaxşı təcrübələr

Qayda 1: Standart olaraq sahələri private edin

Bu, inkapsulyasiyanın əsas prinsipidir. Sahələr sinfin özündən başqa hamıdan gizli olmalıdır. Əgər giriş vermək lazımdırsa — getter/setter-lərdən istifadə edin.

public class Book {
    private String title;
    private int pages;

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
}

Qayda 2: Yalnız zəruri metodları açın

Əgər metod kənardan əlçatan olmalıdırsa — onu public edin. Yalnız paket daxilində lazımdırsa — package-private saxlayın. Metod yalnız varislər üçün nəzərdə tutulubsa — protected istifadə edin.

Qayda 3: Görünürlük sahəsini minimuma endirin

Görünürlük sahəsi nə qədər kiçikdirsə, təsadüfi səhvlər və “gözlənilməz qonaqlar” ehtimalı da o qədər azdır. Zərurət olmadıqca metod və sahələri public etməyin.

Qayda 4: Girişə nəzarət üçün getter və setter-lərdən istifadə edin

Bu, sahəni oxuyarkən/yazarkən əlavə məntiq (məsələn, validasiya) əlavə etməyə imkan verir.

public class Account {
    private double balance;

    public void setBalance(double balance) {
        if (balance < 0) {
            throw new IllegalArgumentException("Balans mənfi ola bilməz!");
        }
        this.balance = balance;
    }

    public double getBalance() {
        return balance;
    }
}

Qayda 5: Daxili reallaşdırmanı açmayın

Əgər sahə kimi massiv və ya siyahı saxlayırsınızsa, onu getter vasitəsilə birbaşa qaytarmayın — nüsxə qaytarın və ya yalnız lazım olan metodları təqdim edin.

public class Team {
    private List<String> members = new ArrayList<>();

    // Düzgün:
    public List<String> getMembers() {
        return new ArrayList<>(members); // nüsxəni qaytarırıq
    }
}

4. Praktik nümunələr

Tutaq ki, bizdə kitabxana istifadəçisini təsvir edən LibraryUser sinfi var.

Yanlış reallaşdırma nümunəsi

public class LibraryUser {
    public String name;
    public int borrowedBooks;
}

Bu halda istənilən kod obyektlə istədiyini edə bilər:

LibraryUser user = new LibraryUser();
user.name = null;
user.borrowedBooks = -10; // Məntiq? Hansı məntiq?

İnkapsulyasiyalı düzgün reallaşdırma nümunəsi

public class LibraryUser {
    private String name;
    private int borrowedBooks;

    public LibraryUser(String name) {
        this.name = name;
        this.borrowedBooks = 0;
    }

    public String getName() {
        return name;
    }

    public int getBorrowedBooks() {
        return borrowedBooks;
    }

    public void borrowBook() {
        borrowedBooks++;
    }

    public void returnBook() {
        if (borrowedBooks > 0) {
            borrowedBooks--;
        }
    }
}

Artıq kənar kod götürülən kitabların sayını və ya istifadəçinin adını birbaşa dəyişə bilməz. Hər şeyə nəzarət yalnız sinfin metodları vasitəsilə həyata keçirilir.

5. Reallaşdırmanın xüsusiyyətləri və nüansları

Bəzən elə gəlir ki, bir sahəni public etmək, çoxlu getter və setter yazmaqdan daha asandır. Amma bu, tələdir! Açıq sahə — mənzilə açıq qapı kimidir: bəli, rahatdır, amma o qədər də təhlükəsiz deyil.

Daha bir incəlik — hər sahə üçün getter və setter yazmağa həmişə ehtiyac yoxdur. Əgər sahənin dəyəri obyekt yaradıldıqdan sonra dəyişməməlidirsə, yalnız getter yazın, sahəni isə final edin:

public class Passport {
    private final String number;

    public Passport(String number) {
        this.number = number;
    }

    public String getNumber() {
        return number;
    }
}

Həmçinin yadda saxlayın: əgər sinif public elan edilibsə, faylın adı sinfin adı ilə eyni olmalıdır! Bu, tam olaraq giriş modifikatorları barədə olmasa da, yeni başlayanların çox etdiyi bir səhvdir.

6. Giriş modifikatorları ilə işləyərkən tipik səhvlər

Səhv №1: sahə və ya metod üçün giriş modifikatorunu göstərməyi unutmusunuz. Nəticədə sahə və ya metod bütün paketdə əlçatan olur, halbuki bunu istəməmişdiniz. IDE xəbərdarlıq etməsə belə, modifikatoru həmişə açıq şəkildə göstərin.

Səhv №2: bütün sahələr public kimi elan edilib. Bu, inkapsulyasiyanı məhv edir, kodunuzu həssas və proqnozlaşdırılmaz edir. “Sadəlik üçün” nümunələrindən qalan vərdiş iş koduna düşməməlidir.

Səhv №3: başqa sinifdən private sahəyə müraciət cəhdi. Java buna icazə verməyəcək — kompilyator sizi qoruyacaq, amma əgər bunu “refleksiya vasitəsilə keçmək” istədinizsə — ümumiyyətlə niyə belə bir ehtiyacın yarandığını düşünün.

Səhv №4: protected üzvlərin mirasalma olan hər yerdə əlçatan olacağını gözləmək. Əslində, paketdən kənarda onlara yalnız alt sinifdən və yalnız this vasitəsilə və ya alt sinif obyektindən müraciət etmək olar.

Səhv №5: daxili kolleksiyanı getter vasitəsilə qaytarmaq. Əgər daxili massivə və ya siyahıya istinad qaytarsanız, kənar kod onu dəyişə bilər və bu da sinfin invariantlarını poza bilər.

Səhv №6: setter vasitəsilə dəyər təyin edilərkən nəzarətin olmaması. Gələn dəyəri yoxlamasanız, obyektin qeyri-korrekt vəziyyətini ala bilərsiniz (məsələn, mənfi balans).

Səhv №7: metodların həddindən artıq geniş görünürlüyü. Bəzən metodlar public edilir, baxmayaraq ki, onlar yalnız paket və ya sinif daxilində lazımdır. Bu, artıq API-ni açır və dəstəyi çətinləşdirir.

1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Sadə avtosalon kataloqu 🚗
Sadə avtosalon kataloqu 🚗
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Onlayn mağazada qiymətlərin təhlükəsiz idarə edilməsi 💰
Onlayn mağazada qiymətlərin təhlükəsiz idarə edilməsi 💰
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Şifrə mühafizəsi: Heç bir boşluq yoxdur! 🔐
Şifrə mühafizəsi: Heç bir boşluq yoxdur! 🔐
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Zooparkda kim "danışa" bilər? 🐾
Zooparkda kim "danışa" bilər? 🐾
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION