Share via


Rozhraní (C++/CX)

Ačkoli ref třída může dědit z nejvýše jedné konkrétní základní třídy, může implementovat libovolný počet tříd rozhraní. Samotná třída rozhraní (nebo struktura rozhraní) může dědit (nebo vyžadovat) více tříd rozhraní, může přetížit své členské funkce a může mít parametry typu.

Charakteristiky

Rozhraní má tyto vlastnosti:

  • Třída rozhraní (nebo struktura) musí být deklarována v rámci oboru názvů a může mít veřejnou nebo privátní přístupnost. Metadata se generují pouze veřejná rozhraní.

  • Členy rozhraní mohou zahrnovat vlastnosti, metody a události.

  • Všichni členové rozhraní jsou implicitně veřejné a virtuální.

  • Pole a statické členy nejsou povoleny.

  • Typy, které se používají jako vlastnosti, parametry metody nebo návratové hodnoty, mohou být pouze prostředí Windows Runtime typy. To zahrnuje základní typy a typy tříd výčtu.

Deklarace a využití

Následující příklad ukazuje, jak deklarovat rozhraní. Všimněte si, že rozhraní lze deklarovat jako třída nebo typ struktury.

namespace InterfacesTest
{
    public enum class PlayState {Playing, Paused, Stopped, Forward, Reverse};

    public ref struct MediaPlayerEventArgs sealed
    {
        property PlayState oldState;
        property PlayState newState;
    };

    public delegate void OnStateChanged(Platform::Object^ sender, MediaPlayerEventArgs^ a);
    public interface class IMediaPlayer // or public interface struct IMediaPlayer 
    {
        event OnStateChanged^ StateChanged;
        property Platform::String^ CurrentTitle;
        property PlayState CurrentState;
        void Play();
        void Pause();
        void Stop();
        void Back(float speed);
        void Forward(float speed);
    };
}

K implementaci rozhraní deklaruje a implementuje virtuální metody a vlastnosti ref třídy ref nebo ref. Rozhraní a implementace třídy ref musí používat stejné názvy parametrů metody, jak je znázorněno v tomto příkladu:

public ref class MyMediaPlayer sealed : public IMediaPlayer
{
public:
    //IMediaPlayer
    virtual event OnStateChanged^ StateChanged;
    virtual property Platform::String^ CurrentTitle;
    virtual property PlayState CurrentState;
    virtual void Play()
    {
        // ...
        auto args = ref new MediaPlayerEventArgs(); 
        args->newState = PlayState::Playing;
        args->oldState = PlayState::Stopped;
        StateChanged(this, args);
    }
    virtual void Pause(){/*...*/}
    virtual void Stop(){/*...*/}
    virtual void Forward(float speed){/*...*/}
    virtual void Back(float speed){/*...*/}
private:
    //...
};

Hierarchie dědičnosti rozhraní

Rozhraní může dědit z jednoho nebo více rozhraní. Na rozdíl od třídy ref nebo struktury však rozhraní nedeklaruje zděděné členy rozhraní. Pokud rozhraní B dědí z rozhraní A a ref třída C dědí z B, C musí implementovat A i B. To je znázorněno v dalším příkladu.

public interface struct A { void DoSomething(); };
public interface struct B : A { void DoSomethingMore();};

public ref struct C sealed : B
{
    virtual void DoSomething(){}
    virtual void DoSomethingMore(){}
};


Implementace vlastností a událostí rozhraní

Jak je znázorněno v předchozím příkladu, můžete k implementaci vlastností rozhraní použít triviální virtuální vlastnosti. V implementovací třídě můžete také zadat vlastní gettery a settery. Getter i setter musí být veřejné ve vlastnosti rozhraní.

//Alternate implementation in MediaPlayer class of IMediaPlayer::CurrentTitle
virtual property Platform::String^ CurrentTitle
{
    Platform::String^ get() {return "Now playing: " + _title;}
    void set(Platform::String^ t) {_title = t; }
}

Pokud rozhraní deklaruje vlastnost get-only nebo set-only, implementace třídy by měla explicitně poskytnout getter nebo setter.

public interface class IMediaPlayer
{
    //...
    property Platform::String^ CurrentTitle
    {
        Platform::String^ get();           
    }
};

public ref class MyMediaPlayer3 sealed : public IMediaPlayer
{
public:
    //...
    virtual property Platform::String^ CurrentTitle
    {
        Platform::String^ get() {return "Now playing: " + _title;}
    }
private:
    Platform::String^ _title;
};

Můžete také implementovat vlastní metody přidání a odebrání událostí v implementování třídy.

Explicitní implementace rozhraní

Když ref třída implementuje více rozhraní a tato rozhraní mají metody, jejichž názvy a podpisy jsou identické s kompilátorem, můžete pomocí následující syntaxe explicitně indikovat metodu rozhraní, kterou metoda třídy implementuje.

public interface class IArtist
{     
    Platform::String^ Draw();
};

public interface class ICowboy
{
    Platform::String^ Draw();
};

public ref class MyClass sealed : public IArtist, ICowboy
{
public:     
    MyClass(){}     
    virtual  Platform::String^ ArtistDraw() = IArtist::Draw {return L"Artist";}
    virtual  Platform::String^ CowboyDraw() = ICowboy::Draw {return L"Cowboy";}
};

Obecná rozhraní

V jazyce C++/CX generic se klíčové slovo používá k reprezentaci prostředí Windows Runtime parametrizovaného typu. Parametrizovaný typ se vysílá v metadatech a může ho využívat kód napsaný v libovolném jazyce, který podporuje parametry typu. Prostředí Windows Runtime definuje některá obecná rozhraní, například Windows::Foundation::Collections::IVector<T>, ale nepodporuje vytváření veřejných uživatelsky definovaných obecných rozhraní v C++/CX. Můžete ale vytvořit privátní obecná rozhraní.

Tady je postup, jak prostředí Windows Runtime typy můžete použít k vytvoření obecného rozhraní:

  • Obecný uživatelem definovaný interface class v komponentě není možné ho vysílat do souboru metadat Windows, a proto nemůže mít veřejnou přístupnost a klientský kód v jiných souborech .winmd ho nemůže implementovat. Lze jej implementovat pomocí tříd nepřístupných ref ve stejné komponentě. Veřejná ref třída může mít obecný typ rozhraní jako soukromý člen.

    Následující fragment kódu ukazuje, jak deklarovat obecný interface class a pak ho implementovat v privátní ref třídě a použít třídu ref jako soukromý člen ve veřejné ref třídě.

    public ref class MediaFile sealed {};
    
    generic <typename T>
    private interface class  IFileCollection
    {
        property Windows::Foundation::Collections::IVector<T>^ Files;
        Platform::String^  GetFileInfoAsString(T file);
    };
    
    private ref class MediaFileCollection : IFileCollection<MediaFile^>
    {
    public:
        virtual property Windows::Foundation::Collections::IVector<MediaFile^>^ Files;
        virtual Platform::String^  GetFileInfoAsString(MediaFile^ file){return "";}
    };
    
    public interface class ILibraryClient
    {
        bool FindTitle(Platform::String^ title);       
        //...
    };
    
    public ref class MediaPlayer sealed : public IMediaPlayer, public ILibraryClient
    {
    public:
        //IMediaPlayer
        virtual event OnStateChanged^ StateChanged;
        virtual property Platform::String^ CurrentTitle;
        virtual property PlayState CurrentState;
        virtual void Play()
        {
            auto args = ref new MediaPlayerEventArgs(); 
            args->newState = PlayState::Playing;
            args->oldState = PlayState::Stopped;
            StateChanged(this, args);
        }
        virtual void Pause(){/*...*/}
        virtual void Stop(){/*...*/}
        virtual void Forward(float speed){/*...*/}
        virtual void Back(float speed){/*...*/}
    
        //ILibraryClient
        virtual bool FindTitle(Platform::String^ title){/*...*/ return true;}
    
    private:
        MediaFileCollection^ fileCollection;
    
    };
    
  • Obecné rozhraní musí dodržovat standardní pravidla rozhraní, která řídí přístupnost, členy, vyžaduje relace, základní třídy atd.

  • Obecné rozhraní může mít jeden nebo více obecných parametrů typu, které jsou před typename nebo class. Parametry jiného typu nejsou podporovány.

  • Parametr typu může být libovolný typ prostředí Windows Runtime. To znamená, že parametr typu může být referenčním typem, typem hodnoty, třídou rozhraní, delegátem, základním typem nebo veřejnou výčtovou třídou.

  • Uzavřené obecné rozhraní je rozhraní, které dědí z obecného rozhraní a určuje konkrétní argumenty typu pro všechny parametry typu. Dá se použít kdekoli, kde je možné použít jiné než obecné privátní rozhraní.

  • Otevřené obecné rozhraní je rozhraní , které má jeden nebo více parametrů typu, pro které ještě není k dispozici žádný konkrétní typ. Dá se použít kdekoli, kde lze použít typ, včetně argumentu typu jiného obecného rozhraní.

  • Parametrizovat můžete pouze celé rozhraní, nikoli jednotlivé metody.

  • Parametry typu nelze omezit.

  • Uzavřené obecné rozhraní má implicitně vygenerované UUID. Uživatel nemůže zadat UUID.

  • V rozhraní se předpokládá, že všechny odkazy na aktuální rozhraní (v parametru metody, návratové hodnotě nebo vlastnosti) odkazují na aktuální instanci. Například IMyIntf znamená IMyIntf<T>.

  • Pokud je typem parametru metody parametr typu, deklarace tohoto parametru nebo proměnné používá název parametru typu bez ukazatele, nativního odkazu nebo popisovačů deklarátorů. Jinými slovy, nikdy nezapisujete "T^".

  • Šablonované ref třídy musí být soukromé. Můžou implementovat obecná rozhraní a můžou předat parametr šablony T obecnému argumentu T. Každá instance šablonované třídy ref je sama o sobě referenční třídou.

Viz také

Systém typů
Referenční zdroje k jazyku C++/CX
Referenční informace o oborech názvů