Implementowanie jawnych składowych interfejsu w klasie

Ukończone

W języku C# jawna implementacja interfejsu umożliwia klasie implementowanie składowych interfejsu w sposób, który jest dostępny tylko za pośrednictwem interfejsu, a nie wystąpienia klasy. Jest to przydatne, gdy klasa implementuje wiele interfejsów z członkami, które mają ten sam podpis.

Wiele interfejsów w klasie

Klasa w języku C# może implementować wiele interfejsów, co pozwala na dziedziczenie zachowania z różnych źródeł. Możliwość łączenia wielu interfejsów ma kluczowe znaczenie, ponieważ język C# nie obsługuje dziedziczenia wielu klas. Implementowanie wielu interfejsów umożliwia klasie posiadanie różnych funkcji i zapewnia, że jest zgodny z regułami ustawionymi przez te interfejsy.

  • Interfejsy definiują grupę powiązanych funkcji.
  • Klasa lub struktura musi implementować wszystkie elementy członkowskie interfejsów, które dziedziczy.
  • Interfejsy mogą zawierać metody, właściwości, zdarzenia i indeksatory.

Oto dwa proste interfejsy dla naszego przykładu:

public interface IEnglishDimensions
{
    float Length();
    float Width();
}

public interface IMetricDimensions
{
    float Length();
    float Width();
}

Jawni członkowie interfejsu

W języku C# klasa może dziedziczyć tylko z jednej klasy, ale może implementować wiele interfejsów. Jest to szczególnie ważne, gdy kilka interfejsów ma te same nazwy członków. Aby uniknąć nieporozumień, używamy jawnej implementacji interfejsu.

Implementacja jawnego interfejsu gwarantuje, że każdy element członkowski interfejsu ma unikatową implementację, zapobiegając konfliktom. Wyjaśnia również, do którego interfejsu należy członek, gdy klasa implementuje dwa lub więcej interfejsów z tymi samymi nazwami członków. Implementacja jawnego interfejsu umożliwia klasie spełnienie wymagań wielu interfejsów, zapewniając różnorodne funkcje.

Aby jawnie zaimplementować element członkowski interfejsu, należy dodać nazwę interfejsu i kropkę przed nazwą elementu członkowskiego. Oto przykład:

public class Box : IEnglishDimensions, IMetricDimensions
{
    float IEnglishDimensions.Length()
    {
        return 30.0f;
    }

    float IEnglishDimensions.Width()
    {
        return 20.0f;
    }

    float IMetricDimensions.Length()
    {
        return 76.2f;
    }

    float IMetricDimensions.Width()
    {
        return 50.8f;
    }
}

W tym kodzie Box klasa implementuje dwa interfejsy: IEnglishDimensions i IMetricDimensions. Oba interfejsy mają elementy członkowskie o nazwach Length i Width. Aby uniknąć nieporozumień, każdy członek jest jawnie połączony ze swoim interfejsem.

Uwaga / Notatka

Jawnie zaimplementowane elementy członkowskie interfejsu nie mają modyfikatorów dostępu, takich jak public, privateitp. Dostęp do nich można uzyskać tylko za pośrednictwem wystąpienia interfejsu, a nie klasy. Oznacza to, że nie można wywołać Box.Length(), ale możesz wywołać IEnglishDimensions.Length(), jeśli masz wystąpienie Box, które jest traktowane jako IEnglishDimensions.

Jawne elementy interfejsu

Należy utworzyć wystąpienia interfejsów i wywołać ich członków, aby wykonać i przetestować kod, który korzysta z jawnych członków interfejsu. Dzięki temu poprawna implementacja jest wywoływana na podstawie typu interfejsu.

Box box = new Box();
IEnglishDimensions eDimensions = box;
IMetricDimensions mDimensions = box;

Console.WriteLine($"Length in inches: {eDimensions.Length()}");
Console.WriteLine($"Width in inches: {eDimensions.Width()}");
Console.WriteLine($"Length in centimeters: {mDimensions.Length()}");
Console.WriteLine($"Width in centimeters: {mDimensions.Width()}");

W tym przykładzie wystąpienie klasy Box jest rzutowane zarówno na IEnglishDimensions, jak i na IMetricDimensions, aby uzyskać dostęp do jawnych członków interfejsu. Dane wyjściowe zawierają wymiary zarówno w języku angielskim, jak i w jednostkach metryk.

Length in inches: 30
Width in inches: 20
Length in centimeters: 76.2
Width in centimeters: 50.8

W języku C# można zaimplementować wiele interfejsów w klasie, używając jawnej implementacji interfejsu do rozwiązywania konfliktów nazewnictwa, gdy składowe mają te same sygnatury. Jawnie zaimplementowane elementy członkowskie są dostępne za pośrednictwem wystąpienia interfejsu, a nie wystąpienia klasy, zapewniając prawidłowe działanie i unikając niejednoznaczności. Takie podejście zwiększa łatwość konserwacji kodu, wyraźnie definiując zamierzone zachowanie dla każdego interfejsu, dzięki czemu baza kodu jest łatwiej zrozumieć i rozszerzyć.