Zrozumienie interfejsów jako kontraktów określających zachowanie klasy bez wymuszania konkretnej hierarchii dziedziczenia. Student nauczy się implementować wiele interfejsów w jednej klasie, rozróżniać implementację jawną od niejawnej oraz wykorzystywać systemowy interfejs IComparable<T> do automatycznego sortowania kolekcji.
W Twoim komisie "Auto-Premium" pojawiają się nowe możliwości: sprzedaż krajowa, eksport zagraniczny oraz wynajem długoterminowy. Szybko zauważasz, że dziedziczenie to za mało. Na placu stoją przecież różne obiekty: samochody, motocykle, a czasem nawet drogie akcesoria. Nie wszystkie są na sprzedaż (niektóre to tylko auta demonstracyjne), a niektóre mogą być sprzedawane wyłącznie poza granice kraju. Rozwiązaniem są interfejsy – czyste kontrakty, które mówią "co" dany obiekt potrafi robić (np. być sprzedanym), a nie "czym" merytorycznie jest.
Postanawiasz wprowadzić interfejsy ISprzedawalny i IEksportowalny. Dzięki nim możesz potraktować zupełnie różne obiekty jako grupę elementów "sprzedawalnych" i wyliczyć dla nich łączną wartość, nie martwiąc się czy dany element ma koła, czy silnik. Dodatkowo, aby Twój system był bardziej przyjazny dla klienta, implementujesz standardowy interfejs IComparable. Dzięki niemu lista pojazdów na stronie internetowej komisu będzie mogła zostać automatycznie posortowana od najtańszego do najdroższego auta za pomocą jednego polecenia. To dowód na to, jak wielka moc drzemie w standaryzacji kodu za pomocą interfejsów.
using System;
using System.Collections.Generic;
namespace LaboratoriumOOP
{
// INTERFEJSY: Kontrakty zaczynające się od litery 'I'.
// Nie mogą zawierać pól (tylko właściwości i metody).
public interface ISprzedawalny
{
double Cena { get; set; }
void WystawFakture();
}
public interface IEksportowalny
{
void SprawdzDokumentyCelne();
}
// Dziedziczenie po JEDNEJ klasie i WIELU interfejsach
public class Samochod : Pojazd, ISprzedawalny, IEksportowalny
{
public Samochod(string marka, double cena) : base(marka, cena) { }
// Iplementacja niejawna (Implicit) - dostępna bezpośrednio
public void WystawFakture()
{
Console.WriteLine($"[FINANSE] Wystawiono fakturę VAT na kwotę: {Cena} PLN za samochód {Marka}.");
}
// Implementacja jawna (Explicit) - dostępna tylko po rzutowaniu na interfejs
void IEksportowalny.SprawdzDokumentyCelne()
{
Console.WriteLine($"[EKSPORT] {Marka}: Dokumenty celne zweryfikowane pozytywnie.");
}
}
// Klasa bazowa z implementacją sortowania
public abstract class Pojazd : IComparable<Pojazd>
{
public string Marka { get; set; }
public double Cena { get; set; }
protected Pojazd(string marka, double cena)
{
Marka = marka;
Cena = cena;
}
// Porównywanie obiektów (potrzebne do Sort())
public int CompareTo(Pojazd other)
{
if (other == null) return 1;
return this.Cena.CompareTo(other.Cena);
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("--- ZADANIE 08: Interfejsy i sortowanie ---\n");
List<Pojazd> magazyn = new List<Pojazd>
{
new Samochod("Volvo", 95000),
new Samochod("Trabant", 5000),
new Samochod("Dacia", 45000)
};
Console.WriteLine("1. Lista przed sortowaniem:");
magazyn.ForEach(p => Console.WriteLine($"- {p.Marka}: {p.Cena}"));
// Automatyczne sortowanie dzięki IComparable
magazyn.Sort();
Console.WriteLine("\n2. Lista po sortowaniu (od najtańszego):");
magazyn.ForEach(p => Console.WriteLine($"- {p.Marka}: {p.Cena}"));
Console.WriteLine("\n3. Obsługa interfejsów:");
foreach (var p in magazyn)
{
if (p is ISprzedawalny sprzedaz)
{
sprzedaz.WystawFakture();
}
// Przykład wywołania implementacji jawnej
if (p is IEksportowalny eksport)
{
eksport.SprawdzDokumentyCelne();
}
}
Console.WriteLine("\nNaciśnij dowolny klawisz...");
Console.ReadKey();
}
}
}