Məzmuna keç
Educora
Orta17 dəq9 / 18

Abstrakt siniflər və interfeyslər

abstract siniflər və metodlar, interfeyslər, implements, default metodlar və Comparable interfeysi ilə sıralama.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • abstract sinif və metod yazmaq və onları törəmə siniflərdə reallaşdırmaq
  • İnterfeys elan etmək və sinifdə bir neçə interfeysi reallaşdırmaq
  • Abstrakt sinif ilə interfeys arasında seçim etmək

Keçən dərsdəki Shape sinfinə yenidən baxaq: onun area() metodu 0 qaytarırdı. Amma «sadəcə fiqur» nədir və onun sahəsi niyə sıfırdır? Əslində new Shape() yaratmağın heç bir mənası yoxdur — Shape yalnız ümumi ideyadır. Java belə ideyaları ifadə etmək üçün iki alət təklif edir: abstrakt siniflər və interfeyslər.

Abstrakt siniflər

abstract elan olunmuş sinifdən obyekt yaratmaq olmaz — o, yalnız törəmə siniflər üçün əsasdır. Abstrakt sinifdə abstrakt metodlar ola bilər: onların gövdəsi yoxdur, yalnız başlığı var. Hər törəmə sinif bu metodları mütləq reallaşdırmalıdır. Eyni zamanda abstrakt sinifdə adi sahələr, konstruktorlar və hazır metodlar da ola bilər.

Java
public class Main {
    public static void main(String[] args) {
        Payment[] payments = { new CardPayment(50), new CashPayment(20) };
        for (Payment p : payments) {
            p.process();
        }
    }
}

abstract class Payment {
    protected double amount;

    Payment(double amount) { this.amount = amount; }

    abstract double fee();

    void process() {
        System.out.println(getClass().getSimpleName() + ": " + amount + " + fee " + fee() + " = " + (amount + fee()));
    }
}

class CardPayment extends Payment {
    CardPayment(double amount) { super(amount); }
    @Override double fee() { return amount * 0.02; }
}

class CashPayment extends Payment {
    CashPayment(double amount) { super(amount); }
    @Override double fee() { return 0; }
}
Gözlənilən nəticə
CardPayment: 50.0 + fee 1.0 = 51.0
CashPayment: 20.0 + fee 0.0 = 20.0

Payment sinfi ödənişin necə emal olunduğunu bilir (process metodu), amma komissiyanın nə qədər olduğunu bilmir — bunu hər ödəniş növü özü deyir. getClass().getSimpleName() isə obyektin həqiqi sinfinin adını qaytarır. new Payment(10) yazsan, kompilyator xəta verəcək: Payment is abstract; cannot be instantiated.

İnterfeyslər

Tərif
İnterfeys

Sinfin nə edə bildiyini təsvir edən müqavilə: metodların siyahısı, adətən gövdəsiz. Sinif implements açar sözü ilə interfeysi reallaşdırır və onun bütün abstrakt metodlarını yazmalıdır.

Sinif yalnız bir sinifdən törəyə bilər, amma istənilən sayda interfeysi reallaşdıra bilər. Ördək həm uça, həm üzə bilir, təyyarə isə yalnız uça bilir — halbuki onların ortaq valideyni yoxdur. Java 8-dən başlayaraq interfeysdə gövdəsi olan default metodlar da yazmaq olar: sinif onları olduğu kimi götürə və ya yenidən təyin edə bilər.

Java
public class Main {
    public static void main(String[] args) {
        Duck duck = new Duck();
        Plane plane = new Plane();
        Flyable[] flyers = { duck, plane };
        for (Flyable f : flyers) {
            f.fly();
            f.land();
        }
        duck.swim();
    }
}

interface Flyable {
    void fly();

    default void land() {
        System.out.println("  ...landing safely");
    }
}

interface Swimmable {
    void swim();
}

class Duck implements Flyable, Swimmable {
    public void fly() { System.out.println("Duck flaps its wings"); }
    public void swim() { System.out.println("Duck swims in the lake"); }
}

class Plane implements Flyable {
    public void fly() { System.out.println("Plane starts its engines"); }
    @Override
    public void land() { System.out.println("  ...landing at Heydar Aliyev Airport"); }
}
Gözlənilən nəticə
Duck flaps its wings
  ...landing safely
Plane starts its engines
  ...landing at Heydar Aliyev Airport
Duck swims in the lake

Comparable: standart kitabxananın interfeysi

Java-nın öz kitabxanası da interfeyslər üzərində qurulub. Arrays.sort() ədədləri və sətirləri necə sıralamağı bilir, bəs öz obyektlərini? Sinif Comparable<Product> interfeysini reallaşdırsa və compareTo metodunu yazsa, Arrays.sort() onu da sıralaya biləcək. compareTo mənfi ədəd qaytarırsa, cari obyekt əvvəl gəlir, müsbət ədəd qaytarırsa — sonra, 0 isə bərabərlik deməkdir.

Java
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Product[] cart = {
            new Product("Laptop", 1500),
            new Product("Pen", 1.2),
            new Product("Backpack", 45)
        };
        Arrays.sort(cart);
        System.out.println(Arrays.toString(cart));
    }
}

class Product implements Comparable<Product> {
    private final String name;
    private final double price;

    Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public int compareTo(Product other) {
        return Double.compare(this.price, other.price);
    }

    @Override
    public String toString() { return name + " " + price; }
}
Gözlənilən nəticə
[Pen 1.2, Backpack 45.0, Laptop 1500.0]

Nəyi seçməli?

XüsusiyyətAbstrakt sinifİnterfeys
Açar sözextendsimplements
Neçəsini götürmək olar?yalnız biristənilən sayda
Sahələristənilən sahələryalnız sabitlər
Konstruktorola bilərolmur
Mənası«…-dır» (ödəniş növüdür)«…-a bilir» (ördək uça bilir)

Əsas fikirlər

  • abstract sinifdən obyekt yaratmaq olmur; onun abstrakt metodlarını törəmə siniflər reallaşdırır.
  • İnterfeys sinfin nə edə bildiyini təsvir edən müqavilədir; sinif onu implements ilə reallaşdırır.
  • Sinif bir sinifdən törəyə, amma çoxlu interfeys reallaşdıra bilər.
  • default metodların interfeysdə hazır gövdəsi var.
  • Comparable və compareTo öz obyektlərini Arrays.sort() ilə sıralamağa imkan verir.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
abstract class Animal üçün hansı sətir kompilyasiya olunmur?