Middle
Po co są interfejsy, jeśli istnieją już klasy abstrakcyjne?
sobes.tech AI
Odpowiedź od AI
- Wielodziedziczenie. Klasa może implementować wiele interfejsów, ale dziedziczyć tylko z jednej klasy (w tym abstrakcyjnej).
interface IDrivable {} interface IFlyable {} class Car : IDrivable {} // Dziedziczy tylko z jednej klasy (object domyślnie) class FlyingCar : IDrivable, IFlyable {} // Implementuje wiele interfejsów - Kontrakt bez implementacji. Interfejsy definiują tylko kontrakt (metody, właściwości, zdarzenia, indeksatory) bez żadnej implementacji. Klasy abstrakcyjne mogą zawierać częściowo zaimplementowaną funkcjonalność i pola.
interface IShape { double GetArea(); // Tylko deklaracja } abstract class Shape { public abstract double GetArea(); // Deklaracja public string Color { get; set; } // Implementacja właściwości public void DisplayColor() { Console.WriteLine($"Kolor: {Color}"); // Zaimplementowana metoda } } - Luźne powiązanie (loose coupling). Interfejsy sprzyjają luźnemu powiązaniu między komponentami, ponieważ kod zależy od kontraktu, a nie od konkretnej implementacji klasy. Ułatwia to zamianę jednej implementacji na inną.
- Podział ról. Interfejsy pozwalają określić wyraźne role lub możliwości, które powinna posiadać klasa, niezależnie od jej głównego typu lub hierarchii dziedziczenia.
- Testowanie. Mocki i stuby do testów jednostkowych często tworzone są na podstawie interfejsów, a nie klas abstrakcyjnych, ponieważ te mogą mieć zależności lub złożoną logikę wewnętrzną.
Podsumowując: interfejsy zapewniają elastyczny mechanizm do definiowania kontraktów i osiągania polimorfizmu bez ograniczeń dziedziczenia z jednej klasy bazowej, podczas gdy klasy abstrakcyjne służą do dostarczania częściowej implementacji i podstawowego funkcjonalności, które będą uzupełniane w klasach pochodnych.