Middle
W jakich przypadkach należy używać interfejsu, a w jakich klasy abstrakcyjnej?
sobes.tech AI
Odpowiedź od AI
Używaj interfejsów do określenia kontraktu zachowania, który mogą implementować klasy. Pozwala to osiągnąć polimorfizm i osłabić powiązania między klasami. Klasa może mieć wiele interfejsów, ale tylko jedną klasę bazową.
Używaj klas abstrakcyjnych, gdy masz wspólną implementację części funkcjonalności i chcesz zapewnić podstawową strukturę dla klas pochodnych. Klasy abstrakcyjne mogą zawierać metody abstrakcyjne i zwykłe, a także pola. Są odpowiednie, gdy wymagana jest dziedziczenie "jest".
| Cecha | Interfejs | Klasa abstrakcyjna |
|---|---|---|
| Dziedziczenie wielokrotne | Tak | Nie |
| Implementacja | Nie (do .NET 8 z domyślnymi metodami interfejsu) | Tak, częściowa lub pełna |
| Pola | Nie | Tak |
| Konstruktory | Nie | Tak |
| Typ relacji | "może zrobić" ("has-a") | "jest" ("is-a") |
Przykład użycia interfejsu:
// Definiujemy kontrakt dla obiektów, które potrafią latać
public interface IFlyable
{
void Fly();
}
// Klasa samolotu implementuje interfejs IFlyable
public class Airplane : IFlyable
{
public void Fly()
{
// Implementacja lotu samolotu
Console.WriteLine("Samolot leci");
}
}
// Klasa ptaka również implementuje interfejs IFlyable
public class Bird : IFlyable
{
public void Fly()
{
// Implementacja lotu ptaka
Console.WriteLine("Ptak leci");
}
}
Przykład użycia klasy abstrakcyjnej:
// Abstrakcyjna klasa Animal z ogólną implementacją oddychania
public abstract class Animal
{
public void Breathe()
{
Console.WriteLine("Zwierzę oddycha");
}
// Abstrakcyjna metoda, którą muszą zaimplementować klasy pochodne
public abstract void MakeSound();
}
// Konkretna klasa psa dziedzicząca po Animal
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Hau!");
}
}
// Konkretna klasa kota dziedzicząca po Animal
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Miau!");
}
}