OBJEKTINIS PROGRAMAVIMAS

Java abstrakcija

Abstrakcija paslepia nereikalingas realizacijos detales ir parodo tik esmines objekto galimybes. Java kalboje ją galima įgyvendinti abstrakčiomis klasėmis, abstrakčiais metodais ir sąsajomis.

Ką suteikia abstrakcija?

  • apibrėžia, ką susiję objektai privalo mokėti atlikti;
  • leidžia paslėpti, kaip konkretus veiksmas įgyvendintas;
  • sutelkiamas bendras poklasių kodas;
  • mažėja priklausomybė nuo konkrečių realizacijų;
  • lengviau naudoti polimorfizmą ir pridėti naujus objektų tipus.

abstract klasė ir metodas

abstract yra ne prieigos modifikatorius. Juo galima pažymėti klasę arba metodą:

abstract class Leidinys {
    public abstract void rodytiTipa();

    public void rodytiBusena() {
        System.out.println("Leidinį galima pasiskolinti");
    }
}
  1. Leidinys yra bendra sąvoka, apimanti knygas, žurnalus ir kitus leidinius.
  2. abstract class reiškia, kad ši klasė skirta paveldėti, o ne tiesioginiams objektams kurti.
  3. Abstraktus metodas rodytiTipa() nurodo, ką kiekvienas konkretus leidinys privalės atlikti.
  4. Įprastas metodas rodytiBusena() jau turi kodą, todėl poklasiai gali jį paveldėti nepakeistą.
  5. Šis kodas tik deklaruoja klasę, todėl konsolėje dar nieko neišveda.
Abstrakčios klasės elementai
ElementasSavybė
Abstrakti klasėNegalima tiesiogiai kurti jos objektų; ji paveldima
Abstraktus metodasNeturi metodo kūno; realizaciją pateikia konkretus poklasis
Įprastas metodasTuri kūną ir gali būti paveldėtas toks, koks yra

Abstrakčios klasės objekto sukurti negalima

Leidinys leidinys = new Leidinys();
// Klaida: abstrakčios klasės objekto sukurti negalima
Kompiliatoriaus klaida

error: Leidinys is abstract; cannot be instantiated

Leidinys aprašo tik bendrą idėją. Norint sukurti objektą, pirmiausia reikia konkretaus poklasio, pavyzdžiui, Knyga.

Abstraktaus metodo realizavimas

Konkretus poklasis paveldi abstrakčią klasę ir privalo realizuoti jos abstrakčius metodus:

abstract class Leidinys {
    public abstract void rodytiTipa();

    public void rodytiBusena() {
        System.out.println("Leidinį galima pasiskolinti");
    }
}

class Knyga extends Leidinys {
    @Override
    public void rodytiTipa() {
        System.out.println("Tai yra knyga");
    }
}
  1. Knyga extends Leidinys sukuria konkretų leidinio poklasį.
  2. Klasė Knyga privalo parašyti abstraktaus metodo rodytiTipa() kūną.
  3. Metodo kūnas nusprendžia, ką programa atliks iškvietus šį metodą knygos objektui.
  4. Šiame bloke metodas dar nekviečiamas, todėl konsolės rezultato nėra.

Jei konkretus poklasis neįgyvendina visų paveldėtų abstrakčių metodų, jis pats taip pat turi būti pažymėtas abstract.

Konkretaus objekto naudojimas

public class Main {
    public static void main(String[] args) {
        Knyga knyga = new Knyga();

        knyga.rodytiTipa();
        knyga.rodytiBusena();
    }
}
Konsolės rezultatas

Tai yra knyga
Leidinį galima pasiskolinti

  1. new Knyga() leidžiama, nes Knyga yra konkreti, o ne abstrakti klasė.
  2. rodytiTipa() vykdo klasėje Knyga parašytą realizaciją.
  3. rodytiBusena() vykdo iš abstrakčios klasės paveldėtą paruoštą metodą.

Abstrakti klasė gali turėti konstruktorių

Nors abstrakčios klasės objekto tiesiogiai sukurti negalima, jos konstruktorius inicializuoja bendrą poklasių būseną:

abstract class Leidinys {
    protected String pavadinimas;

    Leidinys(String pavadinimas) {
        this.pavadinimas = pavadinimas;
    }

    public abstract void rodytiInformacija();
}

class Zurnalas extends Leidinys {
    Zurnalas(String pavadinimas) {
        super(pavadinimas);
    }

    @Override
    public void rodytiInformacija() {
        System.out.println("Žurnalas: " + pavadinimas);
    }

    public static void main(String[] args) {
        Zurnalas zurnalas = new Zurnalas("Mokslas šiandien");
        zurnalas.rodytiInformacija();
    }
}
Konsolės rezultatas

Žurnalas: Mokslas šiandien

  1. Kuriant Zurnalas objektą jo konstruktorius gauna pavadinimą.
  2. super(pavadinimas) perduoda reikšmę abstrakčios klasės konstruktoriui.
  3. Leidinys konstruktorius išsaugo bendrą lauką pavadinimas.
  4. Poklasio metodas panaudoja paveldėtą pavadinimą ir išveda informaciją.

Abstrakcija ir polimorfizmas

Abstrakti klasė gali būti bendras skirtingų konkrečių objektų tipas:

abstract class Leidinys {
    public abstract void rodytiTipa();
}

class Knyga extends Leidinys {
    public void rodytiTipa() {
        System.out.println("Tai yra knyga");
    }
}

class Zurnalas extends Leidinys {
    public void rodytiTipa() {
        System.out.println("Tai yra žurnalas");
    }
}

public class Main {
    public static void main(String[] args) {
        Leidinys[] leidiniai = {
            new Knyga(),
            new Zurnalas()
        };

        for (Leidinys leidinys : leidiniai) {
            leidinys.rodytiTipa();
        }
    }
}
Konsolės rezultatas

Tai yra knyga
Tai yra žurnalas

  1. Masyvo tipas yra bendras Leidinys, todėl jame galima laikyti skirtingus jo poklasius.
  2. Ciklas žino tik abstrakčioje klasėje apibrėžtą sutartį – metodą rodytiTipa().
  3. Kiekvienas tikras objektas pateikia savo šio metodo realizaciją.

Kada rinktis abstrakčią klasę?

  • Kai susijusiems poklasiams reikia bendrų laukų arba konstruktoriaus.
  • Kai dalis metodų turi bendrą realizaciją, o dalį privalo pateikti poklasiai.
  • Kai norima uždrausti kurti pernelyg bendros bazinės klasės objektus.
  • Kai klasės sudaro aiškią paveldėjimo hierarchiją.
Abstrakciją galima įgyvendinti ir sąsajomis.

Sąsajos ypač naudingos bendrai elgsenos sutarčiai tarp klasių, kurios nebūtinai dalijasi bendra būsena.