1. Getter və setterlər nədir
Əgər obyekti seyf kimi təsəvvür etsək, onun private sahələri — seyfin içindəki məzmundur, getter və setterlər isə — ayrı bölmələrin açarlarıdır. Getterlər içəridə nə olduğunu öyrənməyə, setterlər isə — ora nəsə yenisini səliqə ilə qoymağa imkan verir (amma sənədlər əvəzinə, məsələn, kirpi qoymasanız yaxşıdır).
Getter
Getter — bu, dəyəri private sahədən qaytaran public metoddur (private). Adətən adı get + sahənin adının böyük hərflə yazılmış forması ilə başlayır.
public class Person {
private String name; // Məxfi sahə
// name sahəsi üçün getter
public String getName() {
return name;
}
}
Setter
Setter — bu, private sahənin dəyərini dəyişməyə imkan verən public metoddur. Onun adı set + sahənin adının böyük hərflə yazılmış forması ilə başlayır.
public class Person {
private String name;
// name sahəsi üçün setter
public void setName(String name) {
this.name = name;
}
}
boolean sahələr üçün
boolean tipli sahələr üçün getter-lərdə is prefiksindən istifadə olunur:
private boolean active;
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
2. Sintaksis və adlandırma konvensiyaları
Java ciddi dildir, amma quru deyil. Elə qəbul edilmiş konvensiyalar var ki, onlar sizin kodunuzu digər tərtibatçılar üçün (və bir ay sonra sizin üçün də) anlaşıqlı edir.
- Getter: public Type getFieldName()
- Setter: public void setFieldName(Type value)
- boolean üçün getter: public boolean isFieldName()
Sahənin adı metodda böyük hərflə yazılır: əgər sahə agedirsə, metodlar getAge() və setAge() olacaq.
Bu konvensiya JavaBeans üslubunu dəstəkləyir ki, bunun sayəsində IDE, kitabxanalar və freymvörklər sizin getter və setterlərinizi avtomatik tapa bilir. Məsələn, əgər siz Spring və ya JavaFX istifadə edirsinizsə, bu metodlar lazım olanda “sehrli şəkildə” çağırılacaq.
3. Kod nümunələri
Gəlin bir tədris layihəsi götürək — sadə “kontaktlar” tətbiqi (telefon kitabçasına bənzər) — və ora düzgün getter və setterlər əlavə edək.
Nümunə: Private sahələri və getter/setterləri olan Contact sinfi
public class Contact {
private String name;
private String phone;
private int age;
private boolean favorite;
// Getterlər
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
public int getAge() {
return age;
}
public boolean isFavorite() {
return favorite;
}
// Setterlər
public void setName(String name) {
this.name = name;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setAge(int age) {
// Validasiyaya nümunə: yaş mənfi olmamalıdır
if (age < 0) {
System.out.println("Yaş mənfi ola bilməz!");
return;
}
this.age = age;
}
public void setFavorite(boolean favorite) {
this.favorite = favorite;
}
}
Tətbiqdə istifadə
Contact friend = new Contact();
friend.setName("Ivan Ivanov");
friend.setPhone("+1-999-123-45-67");
friend.setAge(25);
friend.setFavorite(true);
System.out.println("Ad: " + friend.getName());
System.out.println("Telefon: " + friend.getPhone());
System.out.println("Yaş: " + friend.getAge());
System.out.println("Seçilmiş: " + (friend.isFavorite() ? "Bəli" : "Xeyr"));
Setter-də validasiya nümunəsi
Nəzərə alın ki, setAge setter-ində sadə bir yoxlama əlavə etmişik: əgər yaş mənfidirsə, sahəni dəyişmirik və xəbərdarlıq çıxarırıq. Bu, obyekti qeyri-düzgün verilənlərdən qorumağın sadə yoludur.
4. Ən yaxşı təcrübələr: bunu düzgün necə etmək olar
Bütün sahələrin public setter-i olmaq məcburiyyətində deyil
Bəzən sahə yalnız oxunandır — məsələn, obyekt yaradılarkən təyin olunan və daha dəyişməyən unikal identifikator. Bu halda setter yazılmır:
public class Contact {
private final int id; // final — başlanğıcdan sonra dəyişmək mümkün deyil
public Contact(int id) {
this.id = id;
}
public int getId() {
return id;
}
// setId yoxdur!
}
Girişə nəzarət və validasiya üçün getter/setterlərdən istifadə edin
public void setName(String name) {
if (name == null || name.trim().isEmpty()) {
System.out.println("Ad boş ola bilməz!");
return;
}
this.name = name;
}
Daxili dəyişən obyektləri birbaşa açıqlamayın
Əgər sizdə bir sahə var — məsələn, telefonların siyahısı:
private String[] phones;
Onu birbaşa getter vasitəsilə qaytarmaq lazım deyil:
public String[] getPhones() {
return phones; // Pisdir!
}
Belə kod xarici koda siyahını istənilən kimi dəyişməyə imkan verir — enkapsulyasiyanı pozur!
Daha düzgünü: massivdən kopya qaytarmaq:
public String[] getPhones() {
return Arrays.copyOf(phones, phones.length); // Kopyasını qaytarırıq
}
Yaxud sadəcə klonlamaq:
public String[] getPhones() {
return phones.clone();
}
Getter və setterləri anlaşıqlı və sadə edin
- Getter/setterlərdə mürəkkəb biznes məntiqi yazmayın — onların vəzifəsi sadədir: girişə nəzarət və lazım olduqda validasiya.
- Əgər sahə dəyişməməlidirsə — ümumiyyətlə setter yazmayın.
- Əgər sahə çöldən əlçatan olmamalıdırsa — getter yazmayın.
5. IDE-də getter/setterlərin avtomatik yaradılması
Aksessorları əllə yazmaq — xüsusilə sinifin onlarla sahəsi olanda — o qədər də xoş deyil. Xoşbəxtlikdən, müasir IDE-lər (məsələn, IntelliJ IDEA, Eclipse, plaginlərlə VS Code) onları avtomatik yarada bilir.
IntelliJ IDEA-da
- Sinfi açın, kursoru sinif gövdəsinin içinə qoyun.
- Alt + Insert düyməsini basın (və ya Code -> Generate...).
- Getter and Setter seçin.
- Lazım olan sahələri qeyd edib OK basın.
Voilà! Getter və setterləriniz sanki sehr kimi peyda olacaq.
Eclipse-də
- Sinfi açın.
- Siçanın sağ düyməsi — Source — Generate Getters and Setters...
- Sahələri seçin və OK basın.
VS Code-da (Java Extension Pack ilə)
- Sinif faylını açın.
- Əmr palitrasında (Ctrl+Shift+P) Generate getters and setters yazın.
- Tövsiyələrə əməl edin.
6. Tətbiqinizin inkişafı: enkapsulyasiya iş başında
Öncəki mühazirələrdə siz kontaktları saxlamaq üçün sadə bir tətbiq qurdunuz. İndi onu təkmilləşdirə bilərik: sahələri private edək və girişi yalnız getter/setterlərlə təmin edək.
Əvvəl (pis nümunə):
public class Contact {
public String name;
public String phone;
public int age;
}
Problem: istənilən kod bunu edə bilər:
Contact c = new Contact();
c.age = -1000; // İndi telefon kitabçamızda vampir var!
Sonra (yaxşı nümunə):
public class Contact {
private String name;
private String phone;
private int age;
public void setAge(int age) {
if (age < 0) {
System.out.println("Yaş mənfi ola bilməz!");
return;
}
this.age = age;
}
public int getAge() {
return age;
}
// Qalan getterlər/setterlər...
}
Artıq obyekti çöldən təsadüfən (və ya qəsdən) sındırmaq mümkün deyil.
7. Hesablanan və dəyişməz xüsusiyyətlər üçün getter/setterlər
Bəzən dəyər sahədə saxlanmır, yerindəcə hesablanır:
public class Rectangle {
private int width;
private int height;
public int getArea() {
return width * height;
}
}
Sahə (area) üçün setter lazım deyil — onu birbaşa təyin etmək olmur, yalnız eni və ya hündürlüyü dəyişmək olar.
8. Getter və setterlər: tipik səhvlər
Səhv №1: Getter/setter enkapsulyasiyanı pozur.
Əgər getter daxili dəyişən obyektə (məsələn, siyahıya) birbaşa istinad qaytarırsa, xarici kod bütün yoxlamaları keçərək onu dəyişə bilər. Bu, enkapsulyasiya ideyasını sarsıdır.
Səhv №2: Setter verilənləri validasiya etmir.
Əgər setter dəyəri yoxlamadan sadəcə mənimsəyirsə, obyektdə qeyri-düzgün vəziyyət yarana bilər (məsələn, mənfi yaş və ya boş ad).
Səhv №3: Bütün sahələr üçün setterlərin avtomatik yaradılması.
IDE bütün sahələr üçün setterlər yarada bilər, amma bu, həmişə düzgün deyil! Məsələn, identifikator (id) üçün setter lazım deyil.
Səhv №4: Getter/setterlərdə mürəkkəb məntiq.
Getter və setterlər sadə olmalıdır. Əgər onlarda mürəkkəb biznes məntiqi peyda olursa, onu ayrıca metodlara çıxarmaq lazımdır.
Səhv №5: Adlandırma konvensiyalarının pozulması.
Əgər getter-i getName() əvəzinə fetchName() adlandırsanız, bəzi freymvörklər və kitabxanalar onu tanıya bilməyəcək.
GO TO FULL VERSION