Каква точно е разликата между интерфейс и абстрактен клас?
Интерфейсът е договор: Човекът, който пише интерфейса, казва: "Хей, приемам нещата да изглеждат по този начин", а човекът, който използва интерфейса, казва "ОК, класът, който пиша, изглежда по този начин".
Интерфейсът е празна обвивка. Съществуват само сигнатурите на методите, което означава, че методите нямат тяло. Интерфейсът не може'да прави нищо. Той е просто модел.
Например (псевдокод):
// 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;
}
}
Имплементирането на интерфейс консумира много малко процесор, защото това не е клас, а само куп имена, и следователно не се налага да се правят скъпи прегледи. Това е чудесно, когато е от значение, например при вградените устройства.
Абстрактните класове, за разлика от интерфейсите, са класове. Използването им е по-скъпо, тъй като при наследяване от тях трябва да се извърши търсене.
Абстрактните класове приличат много на интерфейси, но имат нещо повече: Можете да дефинирате поведение за тях. Става дума по-скоро за човек, който казва: "Тези класове трябва да изглеждат по този начин и имат това общо, така че попълнете празните места!".
Например:
// 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");
}
}
Макар че абстрактните класове и интерфейсите би трябвало да са различни понятия, имплементациите понякога правят това твърдение невярно. Понякога те дори не са това, което си мислите, че са.
В Java това правило е строго наложено, докато в PHP интерфейсите са абстрактни класове без декларирани методи.
В Python абстрактните класове са по-скоро програмен трик, който можете да получите от модула ABC, и всъщност е използване на метакласове, а следователно и на класове. А интерфейсите са по-скоро свързани с типизирането на патици в този език и това'е смесица между конвенции и специални методи, които извикват дескриптори (методите __метод_).
Както обикновено при програмирането, има теория, практика и практика на друг език :-)
Обяснение можете да намерите тук: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm
Абстрактен клас е клас, който е само частично имплементиран от програмист. Той може да съдържа един или повече абстрактни методи. Абстрактен метод е просто дефиниция на функция, която служи да каже на програмиста, че методът трябва да бъде имплементиран в дъщерна функция клас.
Интерфейсът е подобен на абстрактен клас; наистина интерфейсите заемат същото пространство от имена като класовете и абстрактните класове. Поради тази причина не можете да да дефинирате интерфейс със същото име като клас. Интерфейсът е напълно абстрактен клас; нито един от неговите методи не е се имплементират и вместо клас подклас от него, се казва, че той е имплементира този интерфейс.
Както и да е, намирам това обяснение на интерфейсите за малко объркващо. По-често срещаното определение е: Интерфейсът дефинира договор, който класовете-имплементатори трябва да изпълняват. Дефиницията на интерфейса се състои от сигнатури на публичните членове, без код за изпълнение.
Това не е точно отговорът на първоначалния въпрос, но след като получите отговор на въпроса за разликата между тях, ще навлезете в дилемата кога да използвате всеки от тях: https://stackoverflow.com/questions/1231985/when-to-use-interfaces-or-abstract-classes-when-to-use-both
Имам ограничени познания по ООП, но разглеждането на интерфейсите като еквивалент на прилагателно в граматиката ми вършеше работа досега (поправете ме, ако този метод е фалшив!). Например имената на интерфейсите са като атрибути или възможности, които можеш да дадеш на един клас, и един клас може да има много такива: ISerializable, ICountable, IList, ICacheable, IHappy, ...