Aký je presne rozdiel medzi rozhraním a abstraktnou triedou?
Rozhranie je zmluva: Osoba, ktorá píše rozhranie, hovorí: "Hej, akceptujem, že veci vyzerajú takto", a osoba, ktorá používa rozhranie, hovorí: "OK, trieda, ktorú napíšem, vyzerá takto".
Rozhranie je prázdna schránka. Sú v ňom len signatúry metód, z čoho vyplýva, že metódy nemajú telo. Rozhranie nemôže'robiť nič. Je to len vzor.
Napríklad (pseudokód):
Jazyk: java -->
// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();
int getFuel();
}
// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{
int fuel;
void run()
{
print("Wrroooooooom");
}
int getFuel()
{
return this.fuel;
}
}
Implementácia rozhrania spotrebuje veľmi málo procesora, pretože to nie je trieda, len hromada mien, a preto nie je potrebné robiť žiadne drahé vyhľadávanie. Je to skvelé, keď je to dôležité, napríklad vo vstavaných zariadeniach.
Abstraktné triedy sú na rozdiel od rozhraní triedami. Ich používanie je nákladnejšie, pretože pri dedení z nich je potrebné vykonať vyhľadávanie.
Abstraktné triedy sa veľmi podobajú na rozhrania, ale majú niečo navyše: Môžete pre ne definovať správanie. Je to skôr o tom, že človek povie: "Tieto triedy by mali vyzerať takto a majú toto spoločné, takže doplňte prázdne miesta!".
Napríklad:
// I say all motor vehicles should look like this:
abstract class MotorVehicle
{
int fuel;
// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}
// That can be very different, force them to provide their
// own implementation.
abstract void run();
}
// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}
Hoci abstraktné triedy a rozhrania by mali byť odlišné koncepty, implementácie toto tvrdenie niekedy robia nepravdivým. Niekedy dokonca nie sú tým, čím si myslíte, že sú.
V jazyku Java je toto pravidlo prísne dodržiavané, zatiaľ čo v jazyku PHP sú rozhrania abstraktné triedy bez deklarovaných metód.
V Pythone sú abstraktné triedy skôr programátorským trikom, ktorý môžete získať z modulu ABC, a v skutočnosti používa metatriedy, a teda triedy. A rozhrania v tomto jazyku súvisia skôr s kačacím typovaním a je to'zmes konvencií a špeciálnych metód, ktoré volajú deskriptory (metódy __metódy_).
Ako to už pri programovaní býva, je tu teória, prax a prax v inom jazyku :-)
Vysvetlenie nájdete tu: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm
Abstraktná trieda je trieda, ktorá je implementovaná len čiastočne programátor. Môže obsahovať jednu alebo viac abstraktných metód. Abstraktná metóda je jednoducho definícia funkcie, ktorá slúži na to, aby programátorovi povedala, že metóda musí byť implementovaná v podriadenej funkcii triede.
Rozhranie je podobné abstraktnej triede; rozhrania totiž zaberajú rovnaký menný priestor ako triedy a abstraktné triedy. Z tohto dôvodu nemôžete definovať rozhranie s rovnakým názvom ako trieda. Rozhranie je plne abstraktná trieda; žiadna z jej metód sú implementované a namiesto triedy podtriedy z nej, hovorí sa, že implementovať toto rozhranie.
Každopádne mi toto vysvetlenie rozhraní pripadá trochu mätúce. Bežnejšia definícia je: Rozhranie definuje zmluvu, ktorú musia implementujúce triedy splniť. Definícia rozhrania pozostáva zo signatúr verejných členov bez implementačného kódu.
Nie je to síce odpoveď na pôvodnú otázku, ale akonáhle budete mať odpoveď na rozdiel medzi nimi, dostanete sa k dileme kedy použiť každý z nich: https://stackoverflow.com/questions/1231985/when-to-use-interfaces-or-abstract-classes-when-to-use-both
Mám'obmedzené znalosti OOP, ale vnímanie rozhraní ako ekvivalentu prídavného mena v gramatike mi doteraz fungovalo (opravte ma, ak je táto metóda falošná!). Napríklad názvy rozhraní sú ako atribúty alebo schopnosti, ktoré môžete dať triede, a trieda ich môže mať veľa: ISerializable, ICountable, IList, ICacheable, IHappy, ...