Ja zauważyłem sprawę w C# i Java, ale pytanie może dotyczyć każdego języka z klasami i interfejsami. Nie chodzi mi o szkolne projekciki, których głównym celem jest zapoznanie się i przetestowanie pewnych elementów języka. Chodzi mi o to, czy w praktycznym programowaniu interfejsy mają sens.
ZTCW, interfejs to jaki byt podobny do klasy, który zawiera tylko nazwy i parametry metod, a każda klasa implementująca dany interfejs musi zawierać implementacje metod wymienionych w interfejsie.
Ja nieraz, jak coś programowałem, to miałem wizję dwóch wariantów danego obiektu, więc tworzyłem interfejs zawierający zapis metod, gdyż same metody były odmienne w poszczególnych wariantach. Jednakże, prędzej czy później jakiś kawałek kodu, funkcja wykorzystywana w metodach była podobna, a nieraz taka sama w co najmniej dwóch wariantach. Aby nie dublować kodu, byłem zmuszony zaimplementować funkcję w interfejsie, a interfejs przerobić na klasę. W tym momencie dwie klasy implementujące jeden interfejs zmieniają się na dwie klasy dziedziczące po jednej klasie. Jednak z miejscach wykorzystywania interfejsu i klas nie musiałem robić samych zmian.
W drugą stronę patrząc, jeżeli interfejs w danym przypadku miałbym zastosowanie, to moim zdaniem nie ma żadnej różnicy, czy zaimplementuje się interfejs, czy klasę abstrakcyjną z metodami abstrakcyjnymi, ponieważ:
- W jednym i drugim przypadku klasa pochodna musi implementować metody klasy nadrzędnej lub interfejsu.
- Pole typu klasy nadrzędnej lub interfejsu raz może być obiektem jednej, a raz może być obiektem innej klasy podrzędnej.
- Nie można utworzyć obiektu ani typu interfejsu ani typu klasy abstrakcyjnej.
Wobec powyższego wychodzi na to, że klasa abstrakcyjna i interfejs to jest to samo z tą różnicą, że klasa abstrakcyjna może mieć w sobie jakieś pola lub metody, które są wspólne dla klas wykorzystujących interfejs.
Czy interfejsy mają faktycznie jakiś sens i jaki sens? Czy to jest tylko zaszłość historyczna lub mało użyteczny bajer?
Skoro klasa abstrakcyjna ma cechy podobne do interfejsu a ma większe możliwości, to po co wymyślono interfejsy?
Przykład pierwszy z brzegu: link
interface IEquatable<T>
{
bool Equals(T obj);
}
public class Car : IEquatable<Car>
{
public string? Make { get; set; }
public string? Model { get; set; }
public string? Year { get; set; }
// Implementation of IEquatable<T> interface
public bool Equals(Car? car)
{
return (this.Make, this.Model, this.Year) ==
(car?.Make, car?.Model, car?.Year);
}
}
Może być też tak:
abstract class IEquatable<T>
{
abstract bool Equals(T obj);
}
public class Car : IEquatable<Car>
{
public string? Make { get; set; }
public string? Model { get; set; }
public string? Year { get; set; }
// Implementation of IEquatable<T> interface
public override bool Equals(Car? car)
{
return (this.Make, this.Model, this.Year) ==
(car?.Make, car?.Model, car?.Year);
}
}
To jest to samo, prawda?