Abstraktní třída je taková třída, jejíž instance nelze přímo vytvářet. K čemu je tedy užitečná? Slouží jako společný předek, na základě kterého vytváříme odvozené třídy. Přitom se využívá tzv. dědičnost - odvozená třída (potomek) dědí členské proměnné a metody po své rodičovské třídě. Ukažme si, jak může, například, vypadat společný předek všech geometrických útvarů - abstraktní třída Utvar
:
abstract class Utvar { protected String barva; public Utvar() { } public void setBarva(String barva) { this.barva = barva; } public String getBarva() { return barva; } abstract public double obsah(); }
Instanci třídy Utvar
není možné vytvořit, je to abstraktní třída (její definice začíná klíčovým slovem abstract
). Tato třída obsahuje jednu členskou proměnnou barva
a dvě metody pro nastavení a zjištění barvy útvaru. Navíc třída obsahuje metodu obsah()
, u které chybí tělo metody. Jedná se o tzv. abstraktní metodu (klíčové slovo abstract
), jejíž smysl je takový, že každý potomek třídy Utvar
ji musí implementovat, tj. v definici každého potomka musí být tato třída uvedena i včetně svého těla.
Nyní se podívejte, jak může vypadat definice potomka abstraktní třídy Utvar
. Bude se jednat o třídu Bod
(bod je z hlediska geometrického také útvar, i když velmi jednoduchý).
public class Bod extends Utvar { private int x, y; public Bod() { x = 0; y = 0; } public double obsah() { return 0; } public void info() { System.out.println("Bod [" + x + "," + y + "]"); } }
Všimněte si klíčového slova extends
hned za názvem třídy. Tímto způsobem se v Javě vyjadřuje fakt, že třída Bod
je potomkem třídy Utvar
. Co to v praxi znamená? Třída Bod
zdědí všechny členské proměnné i metody rodičovské třídy Utvar
. Aniž bychom tedy v definici třídy Bod
uvedli proměnnou barva
, bude ji tato třída mít, protože je zdědila od třídy Utvar
. Podobně je to s metodami setBarva()
a getBarva()
. Trochu jinak je to s metodou obsah()
, ta byla ve třídě Utvar
definována jako abstraktní a proto musí být ve třídě bod
uvedena i včetně svého těla. To je správný přístup, neboť obsah každého útvaru se počítá trochu jinak, například bod má vždy nulový obsah. Do definice třídy Bod
jsme přidali ještě metodu info()
, ta slouží pro výpis informací o daném útvaru, v našem případě vypíše pouze souřadnice bodu.
Nyní se podívejte, jak může vypadat definice jiného potomka abstraktní třídy Utvar
. Bude se jednat o třídu Kruh
(bod je z hlediska geometrického také útvar, i když velmi jednoduchý).
public class Kruznice extends Utvar { private int x, y, r; public Kruznice() { x = 0; y = 0; r = 1; } public double obsah() { return Math.PI*r*r; } public void info() { System.out.println("Kruznice [" + x + "," + y + "], r=" + r); } }
Výše uvedené třídy otestujeme pomocí třídy Test
. Jednotlivé třídy je vhodné umístit samostatně do souborů s názvy totožnými s názvy tříd (třídy mohou být i v jednom souboru, ale při větším počtu tříd je to nepřehledné).
class Test { public static void main(String[] args) { Bod A = new Bod(); A.info(); System.out.println("Obsah: " + A.obsah()); Kruznice k = new Kruznice(); k.info(); System.out.println("Obsah: " + k.obsah()); } }