Menu
Coddy logo textTech

Wiele interfejsów

Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 27 z 70.

Chociaż klasa może dziedziczyć tylko po jednej klasie bazowej, może implementować tyle interfejsów, ile potrzeba. To jedna z kluczowych zalet interfejsów w porównaniu z klasami abstrakcyjnymi — pozwalają klasie przyjmować wiele zachowań.

Aby zaimplementować wiele interfejsów, po prostu wymień je po dwukropku, oddzielając przecinkami:

public interface IFlyable
{
    void Fly();
}

public interface ISwimmable
{
    void Swim();
}

public class Duck : IFlyable, ISwimmable
{
    public void Fly()
    {
        Console.WriteLine("Flying through the air");
    }
    
    public void Swim()
    {
        Console.WriteLine("Swimming in the pond");
    }
}

Klasa Duck musi implementować wszystkie składowe obu interfejsów. W naturalny sposób odzwierciedla to rzeczywiste sytuacje — kaczka naprawdę potrafi zarówno latać, jak i pływać, więc ma sens, że spełnia oba kontrakty.

W przypadku łączenia dziedziczenia z wieloma interfejsami klasa bazowa musi wystąpić jako pierwsza:

public class Duck : Bird, IFlyable, ISwimmable
{
    // Dziedziczy po Bird, implementuje oba interfejsy
}

Ta elastyczność pozwala łączyć zachowania z wielu źródeł. Robot może implementować IMovable, IChargeable i ISpeakable. Każdy interfejs reprezentuje pojedynczą możliwość, a Twoja klasa może dowolnie łączyć dokładnie te elementy, których potrzebuje.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system inteligentnych urządzeń domowych, który pokaże, jak jedna klasa może implementować wiele interfejsów, aby zyskać różne możliwości. Utworzysz urządzenia, którymi można sterować i które mają funkcje zarządzania zasilaniem.

Rozmieścisz kod w czterech plikach:

  • IControllable.cs: Zdefiniuj interfejs o nazwie IControllable w przestrzeni nazw SmartHome. Ten interfejs reprezentuje urządzenia, które można włączać i wyłączać. Powinien deklarować dwie metody: TurnOn() i TurnOff(), z których każda zwraca ciąg znaków.
  • INetworkConnected.cs: Zdefiniuj interfejs o nazwie INetworkConnected w przestrzeni nazw SmartHome. Ten interfejs reprezentuje urządzenia, które mogą łączyć się z siecią. Powinien deklarować metodę Connect(string network), która zwraca ciąg znaków.
  • SmartTV.cs: Zdefiniuj klasę SmartTV w przestrzeni nazw SmartHome, która implementuje zarówno IControllable, jak i INetworkConnected. Telewizor powinien mieć właściwość Brand (string) i właściwość ScreenSize (int, reprezentującą cale). Utwórz konstruktor przyjmujący obie wartości. Zaimplementuj wszystkie metody interfejsów:
    • TurnOn() zwraca "{Brand} {ScreenSize}-inch TV is now ON"
    • TurnOff() zwraca "{Brand} {ScreenSize}-inch TV is now OFF"
    • Connect(string network) zwraca "{Brand} TV connected to {network}"
  • Program.cs: W pliku głównym utwórz obiekt SmartTV przy użyciu wartości wejściowych. Pokaż elastyczność wielu interfejsów, przechowując ten sam obiekt telewizora w trzech zmiennych różnych typów: konkretnego typu SmartTV, zmiennej typu IControllable i zmiennej typu INetworkConnected. Wywołaj odpowiednie metody za pośrednictwem każdego odwołania, aby pokazać, jak ten sam obiekt można traktować na różne sposoby, w zależności od używanego interfejsu.

Otrzymasz trzy dane wejściowe:

  • Nazwa marki telewizora
  • Przekątna ekranu w calach
  • Nazwa sieci, z którą ma się połączyć

Wypisz dane wyjściowe w tym formacie:

Via SmartTV:
{TurnOn() result}
{Connect(network) result}
Via IControllable:
{TurnOff() result}
Via INetworkConnected:
{Connect(network) result}

Na przykład, jeśli danymi wejściowymi są Samsung, 55 i HomeWiFi, dane wyjściowe powinny wyglądać następująco:

Via SmartTV:
Samsung 55-inch TV is now ON
Samsung TV connected to HomeWiFi
Via IControllable:
Samsung 55-inch TV is now OFF
Via INetworkConnected:
Samsung TV connected to HomeWiFi

Zwróć uwagę, że do tego samego obiektu SmartTV można uzyskać dostęp za pośrednictwem różnych odwołań do interfejsów. Gdy jest przechowywany jako IControllable, możesz wywoływać tylko metody sterujące. Gdy jest przechowywany jako INetworkConnected, możesz wywoływać tylko metody sieciowe. Na tym polega siła implementowania wielu interfejsów — jedna klasa zyskuje wiele możliwości, zachowując elastyczność sposobu jej użycia!

Spróbuj swoich sił

using System;
using SmartHome;

class Program
{
    public static void Main(string[] args)
    {
        // Wczytaj dane wejściowe
        string brand = Console.ReadLine();
        int screenSize = Convert.ToInt32(Console.ReadLine());
        string network = Console.ReadLine();
        
        // TODO: Utwórz obiekt SmartTV z wartościami wejściowymi
        
        // TODO: Przypisz ten sam obiekt TV do trzech zmiennych różnych typów:
        // 1. Typ SmartTV (klasa konkretna)
        // 2. Typ IControllable (referencja do interfejsu)
        // 3. Typ INetworkConnected (referencja do interfejsu)
        
        // TODO: Wypisz wynik w wymaganym formacie:
        // Via SmartTV:
        // - Wywołaj TurnOn() i Connect(network)
        // Via IControllable:
        // - Wywołaj TurnOff()
        // Via INetworkConnected:
        // - Wywołaj Connect(network)
        
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C# online