Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Även om en referensklass kan ärva från högst en konkret basklass, kan den implementera valfritt antal gränssnittsklasser. En gränssnittsklass (eller gränssnittsstruct) kan ärva (eller kräva) flera gränssnittsklasser, överbelasta dess medlemsfunktioner och kan ha typparametrar.
Egenskaper
Ett gränssnitt har följande egenskaper:
En gränssnittsklass (eller struct) måste deklareras inom ett namnområde och kan ha offentlig eller privat tillgänglighet. Endast offentliga gränssnitt skickas till metadata.
Medlemmarna i ett gränssnitt kan innehålla egenskaper, metoder och händelser.
Alla gränssnittsmedlemmar är implicit offentliga och virtuella.
Fält och statiska medlemmar är inte tillåtna.
Typer som används som egenskaper, metodparametrar eller returvärden kan bara vara Windows Runtime-typer. Detta omfattar de grundläggande typerna och uppräkningsklasstyperna.
Deklaration och användning
I följande exempel visas hur du deklarerar ett gränssnitt. Observera att ett gränssnitt kan deklareras som antingen en klass- eller structtyp.
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);
};
}
För att implementera ett gränssnitt deklarerar och implementerar en referensklass eller referens struct virtuella metoder och egenskaper. Gränssnittet och den implementerande referensklassen måste använda samma metodparameternamn, som du ser i det här exemplet:
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:
//...
};
Gränssnittsarvhierarkier
Ett gränssnitt kan ärva från ett eller flera gränssnitt. Men till skillnad från en referensklass eller struct deklarerar inte ett gränssnitt de ärvda gränssnittsmedlemmarna. Om gränssnitt B ärver från gränssnitt A och referensklass C ärver från B måste C implementera både A och B. Detta visas i nästa exempel.
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(){}
};
Implementera gränssnittsegenskaper och -händelser
Som du ser i föregående exempel kan du använda triviala virtuella egenskaper för att implementera gränssnittsegenskaper. Du kan också ange anpassade getters och setters i implementeringsklassen. Både getter och setter måste vara offentliga i en gränssnittsegenskap.
//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; }
}
Om ett gränssnitt deklarerar en get-only- eller set-only-egenskap bör implementeringsklassen uttryckligen tillhandahålla en getter eller 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;
};
Du kan också implementera anpassade metoder för att lägga till och ta bort för händelser i implementeringsklassen.
Explicit gränssnittsimplementering
När en referensklass implementerar flera gränssnitt, och dessa gränssnitt har metoder vars namn och signaturer är identiska med kompilatorn, kan du använda följande syntax för att uttryckligen ange vilken gränssnittsmetod som en klassmetod implementerar.
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";}
};
Allmänna gränssnitt
I C++/CX används nyckelordet generic för att representera en parameteriserad Windows Runtime-typ. En parameteriserad typ genereras i metadata och kan användas av kod som skrivs på valfritt språk som stöder typparametrar. Windows Runtime definierar vissa allmänna gränssnitt, till exempel Windows::Foundation::Collections::IVector<T>, men det stöder inte skapandet av offentliga användardefinierade allmänna gränssnitt i C++/CX. Du kan dock skapa privata allmänna gränssnitt.
Så här kan Windows Runtime-typer användas för att skapa ett allmänt gränssnitt:
En allmän användardefinierad
interface classi en komponent får inte skickas till dess Windows-metadatafil. Därför kan den inte ha offentlig tillgänglighet och klientkoden i andra .winmd-filer kan inte implementera den. Den kan implementeras av icke-offentliga referensklasser i samma komponent. En offentlig referensklass kan ha en allmän gränssnittstyp som privat medlem.Följande kodfragment visar hur du deklarerar en generisk
interface classoch sedan implementerar den i en privat referensklass och använder referensklassen som privat medlem i en offentlig referensklass.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; };Ett allmänt gränssnitt måste följa standardgränssnittsreglerna som styr tillgänglighet, medlemmar, kräver relationer, basklasser och så vidare.
Ett allmänt gränssnitt kan ha en eller flera generiska typparametrar som föregås av
typenameellerclass. Parametrar som inte är av typen stöds inte.En typparameter kan vara valfri Windows Runtime-typ. Det vill: typparametern kan vara en referenstyp, en värdetyp, en gränssnittsklass, ett ombud, en grundläggande typ eller en offentlig uppräkningsklass.
Ett slutet allmänt gränssnitt är ett gränssnitt som ärver från ett allmänt gränssnitt och anger konkreta typargument för alla typparametrar. Det kan användas var som helst som ett icke-generiskt privat gränssnitt kan användas.
Ett öppet allmänt gränssnitt är ett gränssnitt som har en eller flera typparametrar för vilka ingen konkret typ ännu har angetts. Den kan användas var som helst där en typ kan användas, inklusive som ett typargument för ett annat allmänt gränssnitt.
Du kan bara parametrisera ett helt gränssnitt, inte enskilda metoder.
Typparametrar kan inte begränsas.
Ett stängt allmänt gränssnitt har ett implicit genererat UUID. En användare kan inte ange UUID.
I gränssnittet antas alla referenser till det aktuella gränssnittet – i en metodparameter, returvärde eller egenskap – referera till den aktuella instansieringen. IMyIntf betyder till exempel IMyIntf<T>.
När typen av en metodparameter är en typparameter använder deklarationen av parametern eller variabeln typparameterns namn utan pekare, intern referens eller referensdeklaratorer. Med andra ord skriver du aldrig "T^".
Mallade referensklasser måste vara privata. De kan implementera allmänna gränssnitt och kan skicka mallparametern T till det allmänna argumentet T. Varje instansiering av en mallad referensklass är i sig en referensklass.
Se även
typsystem
C++/CX-språkreferens
referens för namnområden