Megosztás a következőn keresztül:


Adapterek (C++/CX)

Bár a ref osztály legfeljebb egy konkrét alaposztálytól örökölhet, bármilyen számú interfészosztályt implementálhat. Maga az interfészosztály (vagy interfészstruktúra) több illesztőosztályt örökölhet (vagy igényelhet), túlterhelheti tagfüggvényeit, és típusparaméterekkel is rendelkezhet.

Jellemzők

Az interfészek jellemzői a következők:

  • Egy interfészosztályt (vagy szerkezetet) névtéren belül kell deklarálni, és nyilvános vagy privát akadálymentességgel is rendelkezhet. A metaadatokhoz csak nyilvános felületek lesznek kibocsátva.

  • A felület tagjai tulajdonságokat, metódusokat és eseményeket tartalmazhatnak.

  • Minden felületi tag implicit módon nyilvános és virtuális.

  • A mezők és a statikus tagok nem engedélyezettek.

  • A tulajdonságokként, metódusparaméterekként vagy visszatérési értékekként használt típusok csak Windows-futtatókörnyezet-típusok lehetnek; ez magában foglalja az alapvető típusokat és az enumerálási osztálytípusokat.

Deklaráció és használat

Az alábbi példa bemutatja, hogyan deklarálhat egy felületet. Figyelje meg, hogy a felület osztály- vagy struktúratípusként deklarálható.

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);
    };
}

Egy interfész implementálásához egy ref osztály vagy refstruktúra deklarálja és implementálja a virtuális módszereket és tulajdonságokat. Az interfésznek és a implementáló ref osztálynak ugyanazokat a metódusparaméterneveket kell használnia, mint az alábbi példában:

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:
    //...
};

Interfészöröklési hierarchiák

Egy illesztő egy vagy több illesztőtől örökölhet. A ref osztálytól vagy szerkezettől eltérően azonban az interfész nem deklarálja az örökölt illesztőtagokat. Ha a B interfész örökli az A illesztőt, és a C ref osztály a B-től öröklik, a C-nek az A-t és a B-t is implementálnia kell. Ez a következő példában látható.

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(){}
};


Az interfész tulajdonságainak és eseményeinek implementálása

Ahogy az előző példában is látható, triviális virtuális tulajdonságokat használhat az interfésztulajdonságok implementálásához. A implementálási osztályban egyéni gettereket és settereket is megadhat. A lekérésnek és a beállítónak nyilvánosnak kell lennie egy interfésztulajdonságban.

//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; }
}

Ha egy felület csak get-only vagy set-only tulajdonságot deklarál, akkor a implementálási osztálynak explicit módon meg kell adnia egy gettert vagy settert.

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;
};

Egyéni hozzáadási és eltávolítási metódusokat is implementálhat a implementálási osztály eseményeihez.

Explicit felület implementálása

Ha egy ref osztály több illesztőt implementál, és ezek a felületek olyan metódusokkal rendelkeznek, amelyek neve és aláírása megegyezik a fordítóval, az alábbi szintaxissal explicit módon jelezheti az osztálymetódus implementálásának felületmetódusát.

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";}
};

Általános felületek

A C++/CX-ben a generic kulcsszó a Windows futtatókörnyezet paraméteres típusának ábrázolására szolgál. A paraméteres típus a metaadatokban van kibocsátva, és a típusparamétereket támogató bármely nyelven írt kóddal használható. A Windows futtatókörnyezet definiál néhány általános felületet – például Windows::Foundation:::Collections::IVector<T> –, de nem támogatja a nyilvános, felhasználó által definiált általános felületek létrehozását a C++/CX-ben. Azonban létrehozhat magánhálózati általános interfészeket.

A Windows Futtatókörnyezet típusok így használhatók általános felület létrehozásához:

  • Az összetevőben definiált interface class általános felhasználó nem bocsátható ki a Windows metaadatfájljába, ezért nem rendelkezhet nyilvános akadálymentességgel, és más .winmd fájlok ügyfélkódja nem implementálható. Nem nyilvános ref osztályok is implementálhatók ugyanabban az összetevőben. A nyilvános ref-osztály általános felülettípussal rendelkezhet privát tagként.

    Az alábbi kódrészlet bemutatja, hogyan deklarálhat egy általánost interface class , majd implementálhatja egy privát ref osztályban, és hogyan használhatja a ref osztályt privát tagként egy nyilvános ref osztályban.

    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;
    
    };
    
  • Az általános felületnek az akadálymentességet, a tagokat , a kapcsolatokat, az alaposztályokat stb. szabályozó szabványos felületi szabályokat kell követnie.

  • Az általános interfészek egy vagy több általános típusparamétert typename is tartalmazhatnak, amelyek előtt vagy class. A nem típusparaméterek nem támogatottak.

  • A típusparaméter bármilyen Windows-futtatókörnyezet-típus lehet. A típusparaméter lehet referenciatípus, értéktípus, interfészosztály, delegált, alapvető típus vagy nyilvános enumerálási osztály.

  • A zárt általános interfész egy olyan felület, amely egy általános interfésztől öröklődik, és konkrét típusargumentumokat határoz meg az összes típusparaméterhez. Bárhol használható, ahol nem általános privát felület használható.

  • A nyitott általános interfész egy olyan felület, amely egy vagy több típusparamétert biztosít, amelyhez még nincs megadva konkrét típus. Bárhol használható, ahol egy típus használható, beleértve egy másik általános felület típusargumentumaként is.

  • Csak egy teljes felületet paraméterezhet, az egyes metódusokat nem.

  • A típusparaméterek nem korlátozhatók.

  • A zárt általános felület implicit módon generált UUID azonosítóval rendelkezik. A felhasználó nem tudja megadni az UUID azonosítót.

  • Az illesztőben a rendszer feltételezi, hogy az aktuális illesztőre való hivatkozás – egy metódusparaméterben, visszatérési értékben vagy tulajdonságban – az aktuális példányra hivatkozik. Az IMyIntf például azt jelenti, hogy IMyIntf<T>.

  • Ha a metódusparaméter típusa típusparaméter, a paraméter vagy változó deklarációja a típusparaméter nevét használja mutató, natív hivatkozás vagy deklarátorok kezelése nélkül. Más szóval soha nem írod a "T^" szöveget.

  • A sablonalapú hiv-osztályoknak privátnak kell lenniük. Általános interfészeket implementálhatnak, és átadhatják a T sablonparamétert a T általános argumentumnak. A sablonalapú ref-osztály minden példánya önmagában egy ref osztály.

Lásd még

Típus rendszer
C++/CX nyelvi referencia
Névterek – referencia