Klasa je korisnički (definisan) tip podatka, a interfejs ti se u nekim jezicima provlači kao tip podatka.
Dakle, možeš imati IButton interfejs i Button klasu koja implementira taj interfejs, ali ćeš onda negde u nekom kontruktoru, koristeći DI, imati slučaj da ti je parametar kontruktora podatak tipa IButton, a ne tipa Button. Dakle, u tom smislu, IButton je takođe korisnički tip podatka, pa se smatra klasom, a i kod nekih jezika se koristi "class" eventualno uz prefiks "interface" (npr. kod C#).
Razlika između obične klase i interfejsa je očigledna, ali mnogima nije tako očigledna razlika između apstraktne klase i interfejsa. Kod nekih jezika interfejs ne može sadržati atribute, pa se može koristiti apstraktna klasa. Inače, apstraktna klasa i služi isključivo da se na jednom mestu deklarišu/definišu zajednički atributi i metode za više klasa, dok sama klasa nikad neće biti instancirana (npr. klasa "Vehicle" nema potrebe da instancira objekte, jer za to koristimo izvedene klase "Car", "Truck", itd.).
Ili, u realnom primeru, imamo apstraktnu klasu "Document" iz koje su izvedene klase "Report" i sl.
Glavna prednost interfejsa je što može da se sakrije implementacija, ali kod nekih drugih jezika je to moglo da se uradi i drugačije - npr. kod C++ drugom članu tima date samo .hpp fajl gde je deklaracija klase i gde se vidi šta koja metoda radi i koje nazive i parametre ima, ali se ne vidi KAKO je implementirana), kao što je opisano ovde:
https://stackoverflow.com/ques...ss-in-c-into-hpp-and-cpp-files
U nekim drugim jezicima, kao kod C#, interfejsi se koriste npr. za DI i tako injektovan interfejs tretira se kao "service" (bar je tako kod .Core 2 Web API), tako da tu nije moguće interfejs tek tako zameniti apstraktnom ili običnom klasom.
Blessed are those who can laugh at themselves, for they shall never cease to be amused.