Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Embora uma classe ref possa herdar de no máximo uma classe base concreta, ela pode implementar qualquer número de classes de interface. Uma classe de interface (ou estrutura de interface) em si pode herdar (ou exigir) várias classes de interface, pode sobrecarregar suas funções de membro e pode ter parâmetros de tipo.
Caraterísticas
Uma interface tem estas características:
Uma classe de interface (ou struct) deve ser declarada dentro de um namespace e pode ter acessibilidade pública ou privada. Apenas interfaces públicas são emitidas para metadados.
Os membros de uma interface podem incluir propriedades, métodos e eventos.
Todos os membros da interface são implicitamente públicos e virtuais.
Campos e membros estáticos não são permitidos.
Os tipos usados como propriedades, parâmetros de método ou valores de retorno só podem ser tipos do Tempo de Execução do Windows; Isso inclui os tipos fundamentais e os tipos de classe Enum.
Declaração e utilização
O exemplo a seguir mostra como declarar uma interface. Observe que uma interface pode ser declarada como um tipo de classe ou struct.
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);
};
}
Para implementar uma interface, uma classe ref ou ref struct declara e implementa métodos e propriedades virtuais. A interface e a classe ref de implementação devem usar os mesmos nomes de parâmetros de método, conforme mostrado neste exemplo:
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:
//...
};
Hierarquias de herança de interface
Uma interface pode herdar de uma ou mais interfaces. Mas, ao contrário de uma classe ref ou struct, uma interface não declara os membros da interface herdados. Se a interface B herda da interface A e a classe ref C herda da B, C deve implementar A e B. Isso é mostrado no exemplo a seguir.
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(){}
};
Implementando propriedades e eventos da interface
Como mostrado no exemplo anterior, você pode usar propriedades virtuais triviais para implementar propriedades de interface. Você também pode fornecer getters e setters personalizados na classe de implementação. Tanto o getter quanto o setter devem ser públicos em uma propriedade de interface.
//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; }
}
Se uma interface declarar uma propriedade get-only ou set-only, a classe de implementação deve fornecer explicitamente um getter ou 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;
};
Você também pode implementar métodos personalizados de adicionar e remover eventos na classe de implementação.
Implementação de interface explícita
Quando uma classe ref implementa várias interfaces e essas interfaces têm métodos cujos nomes e assinaturas são idênticos ao compilador, você pode usar a sintaxe a seguir para indicar explicitamente o método de interface que um método de classe está implementando.
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";}
};
Interfaces genéricas
Em C++/CX, a generic palavra-chave é usada para representar um tipo parametrizado do Tempo de Execução do Windows. Um tipo parametrizado é emitido em metadados e pode ser consumido por código escrito em qualquer linguagem que suporte parâmetros de tipo. O Tempo de Execução do Windows define algumas interfaces genéricas — por exemplo, Windows::Foundation::Collections::IVector<T> — mas não oferece suporte à criação de interfaces genéricas públicas definidas pelo usuário em C++/CX. No entanto, você pode criar interfaces genéricas privadas.
Veja como os tipos do Tempo de Execução do Windows podem ser usados para criar uma interface genérica:
Um usuário genérico definido
interface classem um componente não pode ser emitido em seu arquivo de metadados do Windows, portanto, ele não pode ter acessibilidade pública e o código do cliente em outros arquivos .winmd não pode implementá-lo. Ele pode ser implementado por classes ref não públicas no mesmo componente. Uma classe ref pública pode ter um tipo de interface genérica como um membro privado.O trecho de código a seguir mostra como declarar um genérico
interface classe, em seguida, implementá-lo em uma classe ref privada e usar a classe ref como um membro privado em uma classe ref pública.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; };Uma interface genérica deve seguir as regras de interface padrão que regem a acessibilidade, membros, requer relacionamentos, classes base e assim por diante.
Uma interface genérica pode usar um ou mais parâmetros de tipo genéricos que são precedidos por
typenameouclass. Não há suporte para parâmetros não-tipo.Um parâmetro type pode ser qualquer tipo do Tempo de Execução do Windows. Ou seja, o parâmetro type pode ser um tipo de referência, um tipo de valor, uma classe de interface, um delegado, um tipo fundamental ou uma classe enum pública.
Uma interface genérica fechada é uma interface que herda de uma interface genérica e especifica argumentos de tipo concretos para todos os parâmetros de tipo. Ele pode ser usado em qualquer lugar que uma interface privada não genérica pode ser usada.
Uma interface genérica aberta é uma interface que tem um ou mais parâmetros de tipo para os quais nenhum tipo concreto ainda é fornecido. Ele pode ser usado em qualquer lugar que um tipo pode ser usado, incluindo como um argumento de tipo de outra interface genérica.
Você pode parametrizar apenas uma interface inteira, não métodos individuais.
Os parâmetros de tipo não podem ser restringidos.
Uma interface genérica fechada tem um UUID gerado implicitamente. Um usuário não pode especificar o UUID.
Na interface, presume-se que qualquer referência à interface atual — em um parâmetro de método, valor de retorno ou propriedade — se refira à instanciação atual. Por exemplo, IMyIntf significa IMyIntf<T>.
Quando o tipo de um parâmetro de método é um parâmetro de tipo, a declaração desse parâmetro ou variável usa o nome do parâmetro type sem qualquer ponteiro, referência nativa ou declaradores de manipulador. Em outras palavras, você nunca escreve "T^".
As classes ref com modelo devem ser privadas. Eles podem implementar interfaces genéricas e podem passar o parâmetro de modelo T para o argumento genérico T. Cada instanciação de uma classe ref modelada é ela própria uma classe ref.
Ver também
Sistema de tipo
Referência da linguagem C++/CX
Referência de namespaces