Abstraktní třída a rozhraní se používají k definování smluv v objektově orientovaném programování, ale existují mezi nimi některé klíčové rozdíly.
Rozdíl mezi abstraktní třídou a rozhraním: -
Definice: Abstraktní třída je třída, která nemůže být konkretizována a může obsahovat jak abstraktní, tak neabstraktní metody. Na druhé straně rozhraní je smlouva, která specifikuje sadu metod, které musí třída implementovat.
Implementace metody: V abstraktní třídě mohou být některé metody implementovány, zatímco jiné jsou ponechány abstraktní, což znamená, že nemají žádnou implementaci a musí být přepsány konkrétními podtřídami. Naproti tomu všechny metody v rozhraní jsou ve výchozím nastavení abstraktní a musí být implementovány jakoukoli třídou, která implementuje rozhraní.
Dědičnost: Třída může dědit pouze z jedné abstraktní třídy, ale může implementovat více rozhraní. Je to proto, že abstraktní třída představuje typ objektu, zatímco rozhraní představuje sadu chování.
Modifikátory přístupu: Abstraktní třídy mohou mít pro své metody a vlastnosti modifikátory přístupu, jako je public, protected a private, zatímco rozhraní mohou mít pouze veřejný přístup.
Proměnné: Abstraktní třída může mít členské proměnné, zatímco rozhraní nikoli.
Stručně řečeno, abstraktní třídy se používají k poskytnutí základní třídy pro konkrétní podtřídy, ze kterých lze dědit, zatímco rozhraní se používají k definování sady metod, které musí třída implementovat. Abstraktní třídy mohou mít implementované a abstraktní metody, zatímco rozhraní mohou mít pouze abstraktní metody. Třídy mohou dědit pouze z jedné abstraktní třídy, ale mohou implementovat více rozhraní.
Jak víme, abstrakce se týká skrytí vnitřní implementace funkce a pouze zobrazení funkce uživatelům. tj. zobrazení pouze požadovaných funkcí a skrytí toho, jak jsou tyto funkce implementovány za scénou. Zatímco rozhraní je dalším způsobem, jak dosáhnout abstrakce v jazyce Java. Oba abstraktní třída a rozhraní se používají pro abstrakci, od nynějška jsou Interface a Abstract Class povinnými předpoklady.

Abstraktní třída vs rozhraní
- Typ metod: Rozhraní může mít pouze abstraktní metody. Zatímco abstraktní třída může mít abstraktní metodu a konkrétní metody. Od Java 8 může mít také výchozí a statické metody. Od Java 9 může mít také soukromé konkrétní metody.
- Poznámka: Konkrétní metody jsou ty metody, které mají svou úplnou definici, ale mohou být také přepsány ve zděděné třídě. Pokud však uděláme konkrétní metodu jako FINÁLE nelze ji přepsat ve zděděné třídě, protože deklarovat metodu jako konečný prostředek – jeho realizace je dokončena .
- Konečné proměnné: Proměnné deklarované v rozhraní Java jsou ve výchozím nastavení konečné. Abstraktní třída může obsahovat nefinální proměnné.
- Typ proměnných: Abstraktní třída může mít konečné, nefinální, statické a nestatické proměnné. Rozhraní má pouze statické a konečné proměnné.
- Implementace: Abstraktní třída může poskytnout implementaci rozhraní. Rozhraní nemůže poskytnout implementaci abstraktní třídy.
- Dědičnost vs abstrakce: Rozhraní Java lze implementovat pomocí klíčového slova nářadí a abstraktní třídu lze rozšířit pomocí klíčového slova rozšiřuje .
- Více implementací: Rozhraní může rozšířit jedno nebo více rozhraní Java; abstraktní třída může rozšířit další třídu Java a implementovat více rozhraní Java.
- Vícenásobná dědičnost: Vícenásobnou dědičnost lze částečně dosáhnout použitím rozhraní , zatímco totéž nelze provést použitím abstraktních tříd. Protože v Javě může jedna třída implementovat více rozhraní, ale jedna třída se nemůže rozšířit z více jiných tříd, protože to v Javě prostě není možné, protože by to vedlo k diamantovému problému.
- Přístupnost datových členů: Členové (proměnné) rozhraní Java jsou ve výchozím nastavení konečné. Abstraktní třída Java může mít členy třídy jako soukromé, chráněné atd.
Vlastnosti abstraktní třídy: -
Abstraktní třída je speciální typ třídy v objektově orientovaném programování, který nelze přímo vytvořit. Místo toho slouží jako plán nebo šablona pro další třídy, ze kterých se mají odvodit. Abstraktní třída:
- Nelze vytvořit instanci : Abstraktní třídy nelze přímo konkretizovat, což znamená, že nemůžete vytvářet objekty abstraktní třídy.
- Obsahuje alespoň jednu čistě virtuální funkci : Abstraktní třídy musí obsahovat alespoň jednu čistě virtuální funkci, což znamená, že funkce nemá žádnou implementaci a musí být implementována libovolnými odvozenými třídami.
- Může obsahovat abstraktní i neabstraktní metody : Abstraktní třídy mohou mít jak abstraktní, tak neabstraktní metody. Neabstraktní metody mají kompletní implementaci a lze je volat přímo.
- Může mít konstruktory a destruktory : Abstraktní třídy mohou mít konstruktory a destruktory jako každá jiná třída.
- Může mít členské proměnné : Abstraktní třídy mohou mít členské proměnné, což jsou proměnné, které patří k objektu třídy.
- Lze použít jako základní třídu : Abstraktní třídy lze použít jako základní třídu pro jiné třídy, což znamená, že mohou být zděděny jinými třídami.
Celkově se abstraktní třídy používají k definování společného rozhraní nebo chování, které může být sdíleno více souvisejícími třídami, ale se specifickými implementacemi v každé odvozené třídě.
Příklad 1: (pro abstraktní třídu)
Jáva abstract class sunstar { abstract void printInfo(); } class employee extends sunstar { void printInfo() { String name = 'avinash'; int age = 21; float salary = 222.2F; System.out.println(name); System.out.println(age); System.out.println(salary); } } class base { public static void main(String args[]) { sunstar s = new employee(); s.printInfo(); } }> Výstup
avinash 21 222.2>
Příklad 2: (pro abstraktní třídu)
Jáva // Java Program to Illustrate Concept of // Abstract Class // Importing required classes import java.io.*; // Class 1 // Helper abstract class abstract class Shape { // Declare fields String objectName = ' '; // Constructor of this class Shape(String name) { this.objectName = name; } // Method // Non-abstract methods // Having as default implementation public void moveTo(int x, int y) { System.out.println(this.objectName + ' ' + 'has been moved to' + ' x = ' + x + ' and y = ' + y); } // Method 2 // Abstract methods which will be // implemented by its subclass(es) abstract public double area(); abstract public void draw(); } // Class 2 // Helper class extending Class 1 class Rectangle extends Shape { // Attributes of rectangle int length, width; // Constructor Rectangle(int length, int width, String name) { // Super keyword refers to current instance itself super(name); // this keyword refers to current instance itself this.length = length; this.width = width; } // Method 1 // To draw rectangle @Override public void draw() { System.out.println('Rectangle has been drawn '); } // Method 2 // To compute rectangle area @Override public double area() { // Length * Breadth return (double)(length * width); } } // Class 3 // Helper class extending Class 1 class Circle extends Shape { // Attributes of a Circle double pi = 3.14; int radius; // Constructor Circle(int radius, String name) { // Super keyword refers to parent class super(name); // This keyword refers to current instance itself this.radius = radius; } // Method 1 // To draw circle @Override public void draw() { // Print statement System.out.println('Circle has been drawn '); } // Method 2 // To compute circle area @Override public double area() { return (double)((pi * radius * radius)); } } // Class 4 // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating the Object of Rectangle class // and using shape class reference. Shape rect = new Rectangle(2, 3, 'Rectangle'); System.out.println('Area of rectangle: ' + rect.area()); rect.moveTo(1, 2); System.out.println(' '); // Creating the Objects of circle class Shape circle = new Circle(2, 'Circle'); System.out.println('Area of circle: ' + circle.area()); circle.moveTo(2, 4); } }> Výstup
Area of rectangle: 6.0 Rectangle has been moved to x = 1 and y = 2 Area of circle: 12.56 Circle has been moved to x = 2 and y = 4>
Co když nemáme žádný společný kód mezi obdélníkem a kruhem, přejděte k rozhraní.
Rozhraní:
Vlastnosti rozhraní:
rozhraní:
- Definuje sadu metod a vlastností: Rozhraní definuje sadu metod a vlastností, které musí implementovat jakákoli třída nebo struktura, která implementuje rozhraní.
- Poskytuje společný protokol: Rozhraní poskytují společný protokol, který umožňuje různým softwarovým komponentám vzájemně komunikovat.
- Podporuje polymorfismus: K dosažení polymorfismu lze použít rozhraní, což znamená, že s objekty různých tříd lze zacházet, jako by patřily ke stejnému typu, pokud implementují stejné rozhraní.
- Umožňuje oddělení obav: Rozhraní umožňují oddělení zájmů, což znamená, že různé části softwarového systému mohou být vyvíjeny nezávisle na sobě, pokud splňují specifikace rozhraní.
- Zlepšuje znovupoužitelnost kódu: Rozhraní zlepšují opětovnou použitelnost kódu tím, že umožňují různým softwarovým komponentám opakovaně používat stejnou základnu kódu, pokud implementují stejné rozhraní.
- Prosazuje designové vzory: Rozhraní lze použít k vynucení návrhových vzorů, jako je vzor Adaptér, tím, že vyžadují implementaci určitých metod nebo vlastností implementačními třídami.
- Usnadňuje testování: Rozhraní usnadňují testování tím, že umožňují testování softwarových komponent nezávisle na sobě pomocí falešných objektů, které implementují rozhraní.
Příklad 1: Pro rozhraní
Jáva // Java Program to Illustrate Concept of Interface // Importing I/O classes import java.io.*; // Interface interface Shape { // Abstract method void draw(); double area(); } // Class 1 // Helper class class Rectangle implements Shape { int length, width; // constructor Rectangle(int length, int width) { this.length = length; this.width = width; } @Override public void draw() { System.out.println('Rectangle has been drawn '); } @Override public double area() { return (double)(length * width); } } // Class 2 // Helper class class Circle implements Shape { double pi = 3.14; int radius; // constructor Circle(int radius) { this.radius = radius; } @Override public void draw() { System.out.println('Circle has been drawn '); } @Override public double area() { return (double)((pi * radius * radius)); } } // Class 3 // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating the Object of Rectangle class // and using shape interface reference. Shape rect = new Rectangle(2, 3); System.out.println('Area of rectangle: ' + rect.area()); // Creating the Objects of circle class Shape circle = new Circle(2); System.out.println('Area of circle: ' + circle.area()); } }> Výstup
Area of rectangle: 6.0 Area of circle: 12.56>
Příklad 2: Pro rozhraní
Jáva // Java Program to Illustrate Concept of Interface // Importing I/O classes import java.io.*; // Interface interface Shape { // Abstract method void draw(); double area(); } // Class 1 // Helper class class Rectangle implements Shape { int length, width; // constructor Rectangle(int length, int width) { this.length = length; this.width = width; } @Override public void draw() { System.out.println('Rectangle has been drawn '); } @Override public double area() { return (double)(length * width); } } // Class 2 // Helper class class Circle implements Shape { double pi = 3.14; int radius; // constructor Circle(int radius) { this.radius = radius; } @Override public void draw() { System.out.println('Circle has been drawn '); } @Override public double area() { return (double)((pi * radius * radius)); } } // Class 3 // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating the Object of Rectangle class // and using shape interface reference. Shape rect = new Rectangle(2, 3); System.out.println('Area of rectangle: ' + rect.area()); // Creating the Objects of circle class Shape circle = new Circle(2); System.out.println('Area of circle: ' + circle.area()); } }> Výstup
Area of rectangle: 6.0 Area of circle: 12.56>
Kdy co použít?
Zvažte použití abstraktních tříd, pokud se na vaši situaci vztahuje některé z těchto tvrzení:
- V aplikaci Java existují některé související třídy, které potřebují sdílet některé řádky kódu, pak můžete tyto řádky kódu vložit do abstraktní třídy a tato abstraktní třída by měla být rozšířena o všechny tyto související třídy.
- Můžete definovat nestatická nebo nefinální pole v abstraktní třídě, takže pomocí metody můžete přistupovat a upravovat stav objektu, ke kterému patří.
- Můžete očekávat, že třídy, které rozšiřují abstraktní třídu, mají mnoho společných metod nebo polí nebo vyžadují modifikátory přístupu jiné než public (jako například protected a private).
Zvažte použití rozhraní, pokud se na vaši situaci vztahuje některé z těchto prohlášení:
- Je to úplná abstrakce, všechny metody deklarované v rozhraní musí být implementovány třídou (třídami), která toto rozhraní implementuje.
- Třída může implementovat více než jedno rozhraní. Říká se tomu vícenásobná dědičnost.
- Chcete určit chování určitého datového typu, ale nezajímá vás, kdo implementuje jeho chování.