1. Statik yuvalanmış sinif
Statik yuvalanmış sinif (static nested class) — başqa bir sinifin daxilində modifikatorla static elan edilən sinifdir. Mahiyyətcə bu, başqa bir sinifin içində “yaşayan”, lakin onun obyekti ilə bağlı olmayan adi sinifdir.
Əgər daxili sinif böyük qardaşının (xarici sinif obyektinin) əlini daim buraxmayan kiçik qardaşa bənzəyirsə, statik yuvalanmış sinif isə yalnız ailə bayramlarına gələn, qalan vaxt öz həyatı olan əmioğludur.
Açar fərqlər:
- Xarici sinif obyektinə örtülü istinad etmir — heç bir OuterClass.this və qeyri‑statik üzvlərə giriş yoxdur.
- Statik üzvlər saxlaya bilər (adi daxili sinifdən fərqli olaraq).
- Xarici sinifin obyekti olmadan yaradılır.
Elan sintaksisi
Statik yuvalanmış sinfi elan etmək çox asandır: xarici sinifin içində static açar sözündən istifadə edirik.
class Outer {
static class Nested {
void print() {
System.out.println("Hello from Nested!");
}
}
}
Vəssalam! Heç bir hiyləli sintaktik konstruksiya — sadəcə static class.
Vizualizasiya:
Outer (xarici sinif)
│
├── Nested (static nested class)
│ └── print()
2. Statik yuvalanmış sinifin nümunəsinin yaradılması
Ən xoşu: xarici sinifin obyektinə ehtiyac yoxdur!
Outer.Nested nested = new Outer.Nested();
nested.print(); // Hello from Nested!
Diqqət edin: biz sinifin tam adından — Outer.Nested — istifadə edirik. Bu, yuvalanmış sinfə soyad vasitəsilə müraciət etməyə bənzəyir: “Smith.Son”.
Daxili (inner) siniflə müqayisə edin:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // outer obyektinə ehtiyac var
Static nested üçün isə ümumiyyətlə Outer obyektinə ehtiyac yoxdur!
3. Xarici sinifin üzvlərinə giriş
Məhz burada daxili sinifdən əsas fərq özünü göstərir.
- Statik yuvalanmış sinif YALNIZ xarici sinifin statik üzvlərinə girişə malikdir.
- Qeyri‑statik sahə və metodlara müraciət etmək olmaz (hətta onlar public olsa belə).
Nümunə:
class Outer {
private static int staticValue = 10;
private int instanceValue = 20;
static class Nested {
void show() {
System.out.println("Static value: " + staticValue); // OK
// System.out.println("Instance value: " + instanceValue); // Səhv!
}
}
}
Əgər instanceValue kimi qeyri‑statik sahəyə müraciət etməyə çalışsanız, kompilyator dərhal etiraz edəcək.
Niyə belədir? Çünki static nested class hansı Outer obyekti ilə əlaqələndiriləcəyini “bilmir” — onun xarici sinif obyektinə istinadı yoxdur.
4. Statik yuvalanmış siniflərdən nə vaxt istifadə etməli
Onlar nə vaxt münasibdir?
- Yuvalanmış sinif məntiqi olaraq xarici siniflə əlaqəlidir, lakin xarici sinif obyektinə giriş tələb etmir.
- Köməkçi strukturu kapsullaşdırmaq istədikdə: məsələn, builder, utilit, enum və ya kiçik dəyişməz (immutable) obyekt.
- Paketin “çirklənməsini” azaltmaq lazım olduqda: sinif yalnız xarici sinifə lazımdırsa, onu kənara çıxarmağa ehtiyac yoxdur.
Tipik ssenarilər:
- Builder nümunəsi (xüsusən də dəyişməz obyektlər üçün)
- Köməkçi strukturların reallaşdırılması: məsələn, kolleksiyalarda daxili Node sinifləri
- Konstantların qruplaşdırılması və ya utilitlər
Sadə seçim qaydası
Özünüzə sual verin: “Yuvalanmış sinifimə xarici sinifin konkret obyektinə giriş lazımdırmı?”
YOX → static class (statik yuvalanmış) istifadə edin
BƏLİ → adi class (daxili/inner) istifadə edin
5. İstifadə nümunələri
Nümunə 1: Sinif üçün Builder
Tutaq ki, bizdə Person sinfi var və onun üçün Builder nümunəsini həyata keçirmək istəyirik:
public class Person {
private final String name;
private final int age;
// Özəl konstruktor
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
}
// Builder üçün statik yuvalanmış sinif
public static class Builder {
private String name;
private int age;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Person build() {
return new Person(this);
}
}
public void printInfo() {
System.out.println("Person: " + name + ", " + age);
}
}
İstifadə:
Person person = new Person.Builder()
.setName("Ivan")
.setAge(30)
.build();
person.printInfo(); // Person: Ivan, 30
Niyə Builder — statik yuvalanmış sinifdir?
Çünki o, Person obyektindən asılı deyil, sadəcə onu yaratmağa kömək edir. O, məntiqi olaraq Person ilə əlaqəlidir, lakin konkret nümunə ilə yox.
Nümunə 2: Kolleksiya daxilində köməkçi struktur
Təsəvvür edək ki, “rəqəmlərdən qutu” sinfi var və elementlərin saxlanması üçün daxili statik Node sinfindən istifadə olunur:
public class IntBox {
private Node head;
// Yuvalanmış static class
private static class Node {
int value;
Node next;
Node(int value) {
this.value = value;
}
}
public void add(int value) {
Node node = new Node(value);
node.next = head;
head = node;
}
public void printAll() {
Node current = head;
while (current != null) {
System.out.println(current.value);
current = current.next;
}
}
}
İstifadə:
IntBox box = new IntBox();
box.add(1);
box.add(2);
box.add(3);
box.printAll(); // 3 2 1
Niyə Node — static-dir?
Çünki hər bir Node bütün qutu (IntBox) barədə “bilməməlidir”; o, sadəcə məlumatı və növbəti Node-a keçidi saxlayır.
Nümunə 3: Əsas sinif daxilində utilit sinif
public class MathUtils {
// Mürəkkəb ədədlərlə işləmək üçün statik yuvalanmış sinif
public static class Complex {
private final double re;
private final double im;
public Complex(double re, double im) {
this.re = re;
this.im = im;
}
public Complex add(Complex other) {
return new Complex(this.re + other.re, this.im + other.im);
}
@Override
public String toString() {
return re + " + " + im + "i";
}
}
}
İstifadə:
MathUtils.Complex a = new MathUtils.Complex(1, 2);
MathUtils.Complex b = new MathUtils.Complex(3, 4);
MathUtils.Complex sum = a.add(b);
System.out.println(sum); // 4.0 + 6.0i
6. Faydalı nüanslar
Daxili sinif vs statik yuvalanmış sinif
| Daxili (inner) sinif | Statik yuvalanmış (static nested) | |
|---|---|---|
| Açar söz | yoxdur | |
| Xarici obyektə örtülü istinad | bəli | yox |
| Xarici sinifin qeyri-statik üzvlərinə giriş | bəli | yox |
| Xarici sinifin statik üzvlərinə giriş | bəli | bəli |
| Statik üzvlər saxlaya bilər | yoxdur (yalnız sabitlər) | bəli |
| Yaradılma sintaksisi | |
|
| İstifadə | Xarici sinifin obyektinə giriş lazım olduqda | Xarici sinifin obyektinə giriş lazım olmadıqda |
İllustrasiya
flowchart LR
OuterClass -->|has| InnerClass
OuterClass -.->|has| StaticNestedClass
StaticNestedClass -.->|can access| staticMembers
InnerClass -->|can access| instanceMembers
InnerClass -->|can access| staticMembers
Xüsusiyyətlər və məhdudiyyətlər
- Static nested class həm adi, həm də statik sahə və metodlara malik ola bilər.
- İstənilən giriş modifikatoru ilə elan oluna bilər (public, private, protected, package-private).
- Interfeysləri reallaşdıra və digər siniflərdən miras ala bilər.
- Generic ola bilər.
- Adətən, xarici sinifdən kənarda lazım olmayan xidmət siniflərini kapsullaşdırmaq üçün istifadə olunur.
Generic static nested class nümunəsi:
public class Box {
public static class Holder<T> {
private T value;
public Holder(T value) { this.value = value; }
public T get() { return value; }
}
}
Static nested class-dan nə zaman istifadə ETMƏMƏK lazımdır
- Əgər yuvalanmış sinfə xarici sinifin qeyri‑statik sahə/metodlarına giriş lazımdırsa — adi inner class istifadə edin.
- Əgər sinif xarici sinifdən kənarda da lazımdırsa — onu ayrıca fayla çıxarın.
- Əgər sinif həddindən artıq böyük və ya mürəkkəbdirsə — onu ayrı etmək daha yaxşıdır.
7. Tipik səhvlər və nüanslar
Səhv № 1: inner və static nested sinifin qarışdırılması.
Bir çox yeni başlayanlar static nested class daxilində xarici sinifin qeyri‑statik sahələrinə müraciət etməyə çalışırlar. Lakin static nested class xarici sinif obyektinə istinada malik deyil, buna görə bu mümkün deyil. Konkret obyektin vəziyyətinə girmək lazımdırsa — adi inner class istifadə edin.
Səhv № 2: static nested class-ı xarici sinifin obyekti vasitəsilə yaratmağa cəhd.
outer.new Inner() yazmağa ehtiyac yoxdur. Static nested class üçün həmişə new Outer.Nested() istifadə edin.
Səhv № 3: xarici sinifin nümunəsinə giriş tələb edən məntiq üçün static nested class istifadə etmək.
Əgər sinifin məntiqi xarici sinif obyektinin vəziyyəti ilə sıx bağlıdırsa, static nested class pis seçimdir. Adi daxili sinifdən istifadə edin.
Səhv № 4: Həddindən artıq dərin yuvalanma.
Yuvalanmış siniflərdən sui‑istifadə etməyin. Struktur dolaşıq hala gəlirsə, bəzi sinifləri bayıra çıxarmaq daha yaxşıdır.
GO TO FULL VERSION