CodeGym /Kurslar /JAVA 25 SELF /Metodları olan record

Metodları olan record

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

1. record sinifinin genişləndirilməsi: əlavə metodlar

Record-a metodlar əlavə etmək olarmı?

Əlbəttə! Record hazır təmiri olan bir mənzil kimidir: divarlar və döşəmə artıq hazırdır, onları dəyişmək olmaz, amma mebeli özün bildiyin kimi düzəltməyə heç kim qadağa qoymur. record-un daxilində adi metodlar, statik metodlar elan etmək və hətta konstansiyalar saxlamaq olar. Bu o deməkdir ki, biznes məntiqini mütləq ayrıca «utilit» siniflərinə çıxarmağa ehtiyac yoxdur — onu səliqəli şəkildə elə record-un özünə daxil etmək olar.

Nümunə: nöqtələr arasında məsafənin hesablanması metodu

Tutaq ki, müstəvidə nöqtə üçün bir recordumuz var:


public record Point(int x, int y) {
    // Əlavə metod
    public double distanceTo(Point other) {
        int dx = this.x - other.x;
        int dy = this.y - other.y;
        return Math.sqrt(dx * dx + dy * dy);
    }
}

İndi bunu belə etmək olar:


Point p1 = new Point(0, 0);
Point p2 = new Point(3, 4);
System.out.println(p1.distanceTo(p2)); // 5.0

Gördüyünüz kimi, record-sinifi öz metodlarınızla “zənginləşdirilə” bilər — bu çox rahatdır!

Nümunə: statik metod


public record Rectangle(int width, int height) {
    public int area() {
        return width * height;
    }

    public static Rectangle square(int size) {
        return new Rectangle(size, size);
    }
}

İndi «kvadrat»ı tək çağırışla yaratmaq olar:


Rectangle r = Rectangle.square(5);
System.out.println(r.area()); // 25

2. Kompakt konstruktor və verilənlərin validasiyası

«Kompakt» konstruktor nə üçün lazımdır?

Kanonik record-konstruktoru avtomatik yaradılır və parametrləri sahələrə təyin edir. Amma bəzən daxil olan məlumatları yoxlamaq istəyirik (məsələn, mənfi koordinatları qadağan etmək).

Adi sinifdə biz belə yazardıq:


public class Point {
    private final int x;
    private final int y;

    public Point(int x, int y) {
        if (x < 0 || y < 0) throw new IllegalArgumentException();
        this.x = x;
        this.y = y;
    }
    // ...
}

record-sinifində kompakt konstruktor elan etmək olar — parametr siyahısını təkrarlamadan və sahələrə açıq təyinat yazmadan (bunları bizim yerimizə kompilyator edir).

Kompakt konstruktorun sintaksisi


public record Point(int x, int y) {
    public Point {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("Coordinates must be non-negative");
        }
        // Bunları yazmağa ehtiyac yoxdur: this.x = x; this.y = y;
    }
}
  • Konstruktorun parametrləri avtomatik olaraq komponentlərlə — record komponentləri ilə — üst-üstə düşür.
  • this.x = xthis.y = y təyinatlarını kompilyator konstruktor bədəni icra olunduqdan (və ya ondan uğurla çıxıldıqdan) sonra avtomatik edir.
  • Əgər istisna atılsa, obyekt yaradılmayacaq.

Yoxlama ilə nümunə


Point p1 = new Point(3, 5); // OK
Point p2 = new Point(-1, 2); // IllegalArgumentException atacaq!

«Adi» konstruktor elan etmək olarmı?

Bəli, olar! Əgər fərqli parametr siyahısı və ya əlavə məntiqi olan konstruktor yaratmaq lazımdırsa, onu açıq şəkildə elan edin:


public record Range(int from, int to) {
    public Range(int size) {
        this(0, size); // əsas konstruktoru çağırır
    }
}

3. record-siniflərinin məhdudiyyətləri

Adi siniflərdən fərqli olaraq, record-siniflərin bir sıra məhdudiyyətləri var. Bunu xatırlamaq vacibdir ki, kompilyasiya xətalarına təəccüblənməyəsiniz.

Yalnız komponentlər — əlavə qeyri-statik sahələr yoxdur

record-sinifində yeni qeyri-statik sahələr elan etmək olmaz:


public record Person(String name, int age) {
    // int id; // Kompilyasiya xətası! Qeyri-statik sahələr əlavə etmək olmaz.
}

Statik sahələr və metodlar elan etmək olar:


public record Person(String name, int age) {
    public static final String SPECIES = "Homo sapiens";
}

Record həmişə final-dır

Record-sinif nə valideyn sinif ola bilər (ondan miras almaq olmaz), nə də özü başqa bir sinifdən açıq şəkildə miras ala bilər (qeyri-aşkar şəkildə java.lang.Record-dan miras almaqdan başqa). Bu o deməkdir ki, record-sinif — həmişə “son” strukturdur.


public record User(String login) { }

// public class Admin extends User {} // Xəta: record-dan irs almaq olmaz!

İnterfeysləri reallaşdırmaq olar

Record-sinif interfeysləri reallaşdıra bilər:


public interface Printable {
    void print();
}

public record Invoice(int amount) implements Printable {
    @Override
    public void print() {
        System.out.println("Məbləğ: " + amount);
    }
}

4. Nümunələr: real tapşırıqlarda genişləndirilmiş record-lar

Gəlin bir neçə praktiki nümunəyə baxaq; burada əlavə metodlar və kompakt konstruktorlar record-sinifini həqiqətən faydalı edir.

Hesablayıcı metoda malik record


public record Circle(double x, double y, double radius) {
    public double area() {
        return Math.PI * radius * radius;
    }

    public double distanceTo(Circle other) {
        double dx = x - other.x;
        double dy = y - other.y;
        return Math.sqrt(dx * dx + dy * dy);
    }
}

Validasiyalı record


public record Email(String value) {
    public Email {
        if (value == null || !value.contains("@")) {
            throw new IllegalArgumentException("Yanlış email: " + value);
        }
    }
}

İndi yanlış email yaratmaq olmaz:


Email e1 = new Email("test@example.com"); // OK
Email e2 = new Email("not-an-email"); // IllegalArgumentException atacaq

Əlavə statik metodları olan record


public record Temperature(double celsius) {
    public static Temperature fromFahrenheit(double fahrenheit) {
        return new Temperature((fahrenheit - 32) * 5 / 9);
    }

    public double toFahrenheit() {
        return celsius * 9 / 5 + 32;
    }
}

İstifadə:


Temperature t = Temperature.fromFahrenheit(98.6);
System.out.println(t.celsius()); // 37.0
System.out.println(t.toFahrenheit()); // 98.6

5. Kompakt konstruktor: incəliklər və məhdudiyyətlər

Kompakt konstruktordan nə vaxt istifadə etməli?

  • Məlumatların düzgünlüyünü yoxlamaq (validasiya) lazım olanda.
  • Saxlamadan əvvəl dəyərləri dəyişmək lazım olanda (məsələn, ədədi yuvarlaqlaşdırmaq və ya sətri böyük hərflərə çevirmək).
  • Parametr siyahısının təkrarlanmasından qaçmaq istəyəndə.

İşləmə xüsusiyyətləri

  • Kompakt konstruktorda komponentlərə açıq şəkildə dəyər təyin etmək olmaz (this.x = ...) — bu kompilyasiya xətasına səbəb olacaq, çünki kompilyator təyinatı konstruktor bədənindən sonra özü yerinə yetirir.
  • Kompakt konstruktorda parametr adlarını dəyişmək olmaz — onlar həmişə record komponentlərinin adları ilə eynidir.

Nümunə: avtomatik yuvarlaqlaşdırma


public record Money(double amount) {
    public Money {
        amount = Math.round(amount * 100) / 100.0; // Məbləği qəpiyə qədər yuvarlaqlaşdırırıq
    }
}

6. Təcrübə: tədris tətbiqini inkişaf etdiririk

Tutaq ki, biz tədris tətbiqində bank əməliyyatları hazırlayırıq. Gəlin record-sinif Transaction olsun; o, məbləği, göndərəni və alıcını saxlayır.


public record Transaction(String from, String to, double amount) {
    public Transaction {
        if (amount <= 0) throw new IllegalArgumentException("Məbləğ müsbət olmalıdır");
        if (from == null || to == null) throw new IllegalArgumentException("Sahələr null ola bilməz");
    }

    public String description() {
        return String.format("Köçürmə %.2f: %s → %s", amount, from, to);
    }
}

İstifadə:


Transaction t = new Transaction("Alice", "Bob", 150.0);
System.out.println(t.description()); // Köçürmə 150.00: Alice → Bob

Yanlış tranzaksiya yaratmağa cəhd xəta yaradacaq:


Transaction t2 = new Transaction("Alice", "Bob", -10.0); // IllegalArgumentException

Cədvəl: record-sinifində nə olar və nə olmaz

Record-sinifində olar Record-sinifində olmaz
Adi metodlar Yeni qeyri-statik sahələr
Statik metodlar və sahələr Digər siniflərdən miras almaq
İnterfeysləri reallaşdırmaq Başqa siniflər üçün superklass olmaq
Kompakt və adi konstruktorlar Yaradıldıqdan sonra komponentləri dəyişmək
Metodları yenidən təyin etmək Setter-lərdən istifadə etmək

7. Standart olmayan bədənə malik record-siniflərlə işləyərkən tipik səhvlər

Səhv № 1: qeyri-statik sahə əlavə etmək cəhdi.
Yeni başlayanlar tez-tez record-sinifə “daxili məntiq üçün daha bir sahə” əlavə etməyə çalışırlar — məsələn, sayğac və ya keş. Bu işləməyəcək: kompilyator dərhal xəta verəcək. Əlavə vəziyyəti (state) saxlamaq lazımdırsa, çox güman, record-sinif düzgün seçim deyil.

Səhv № 2: kompakt konstruktorda validasiyanı unutmaq.
Obyektin həmişə düzgün olmasını istəyirsinizsə, yoxlamanı kompakt konstruktorda edin. “İstifadəçi özü səhv etməz” deyə arxayın olmayın.

Səhv № 3: yaradıldıqdan sonra komponenti dəyişmək cəhdi.
record-sinifin sahələri final-dır — onları nə birbaşa, nə də metodlar vasitəsilə dəyişmək olar. Dəyişən (mutable) struktur lazımdırsa — adi sinifdən istifadə edin.

Səhv № 4: məntiqin metodlarda və konstruktorda təkrarlanması.
Bəzən yoxlama məntiqini və hesablamaları həm metodlarda, həm də konstruktorda təkrarlayırlar. Daha yaxşısı, bütün validasiyanı konstruktorda edin, metodları isə “təmiz” biznes-məntiq üçün saxlayın.

Səhv № 5: irsiyyət məhdudiyyətlərini unutmaq.
Record-sinif həmişə final-dır — ondan törəmə yaratmaq olmaz. Əgər alt-siniflərə ehtiyac olan ierarxiya layihələndirirsinizsə — adi siniflərdən istifadə edin.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION