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.
Uma interface define um contrato. Qualquer class, record, ou struct que implemente esse contrato deve fornecer uma implementação dos membros definidos na interface.
Uma interface pode definir uma implementação padrão para um membro. Ele também pode definir static membros para fornecer uma única implementação para funcionalidade comum.
Uma interface pode definir static abstract ou static virtual membros declarar que um tipo de implementação deve fornecer os membros declarados. Normalmente, static virtual os métodos declaram que uma implementação deve definir um conjunto de operadores sobrecarregados.
A referência da linguagem C# documenta a versão mais recentemente lançada da linguagem C#. Contém também documentação inicial para funcionalidades em versões preliminares públicas para a próxima versão da linguagem.
A documentação identifica qualquer funcionalidade introduzida pela primeira vez nas últimas três versões da língua ou em pré-visualizações públicas atuais.
Sugestão
Para saber quando uma funcionalidade foi introduzida pela primeira vez em C#, consulte o artigo sobre o histórico de versões da linguagem C#.
No exemplo a seguir, a classe ImplementationClass deve implementar um método chamado SampleMethod que não tem parâmetros e retorna void.
interface ISampleInterface
{
void SampleMethod();
}
class ImplementationClass : ISampleInterface
{
// Explicit interface member implementation:
void ISampleInterface.SampleMethod()
{
// Method implementation.
}
static void Main()
{
// Declare an interface instance.
ISampleInterface obj = new ImplementationClass();
// Call the member.
obj.SampleMethod();
}
}
Para obter mais informações e exemplos, consulte Interfaces.
Modificadores de acesso
Uma interface pode ser um membro de um namespace ou uma classe. Pode declarar uma interface de topo, declarada num namespace mas não aninhada dentro de outro tipo, como public ou internal. A predefinição é internal. Podes declarar declarações de interface aninhadas, declaradas dentro de outro tipo, usando qualquer modificador de acesso.
Membros de interface sem implementação (membros abstratos) são implícitos public e não podem ter qualquer outro modificador de acesso. Os membros da interface com uma implementação padrão são private por defeito se não especificares um modificador de acesso, mas podes declarar qualquer modificador de acesso (public, private, protected, ou internal).
Membros da interface
Uma declaração de interface pode conter os seguintes membros:
- Métodos.
- Propriedades.
- Indexadores.
- Eventos.
- Constantes.
- operadores.
- Um construtor estático.
- Tipos aninhados.
- Campos, métodos, propriedades, indexadores e eventos estáticos.
- Modificadores de acesso explícito (o acesso padrão para métodos abstratos é
public).
Membros da interface padrão
As declarações dos membros normalmente não contêm um corpo. No entanto, um membro da interface pode declarar um corpo. Os órgãos membros em uma interface são a implementação padrão. Ao usar membros com corpos, a interface pode fornecer uma implementação padrão para classes e sstrutts que não fornecem uma implementação sobreposta.
Importante
Se adicionares membros de interfaces por defeito, qualquer um ref struct que implemente a interface deve declarar explicitamente esse membro.
Membros estáticos abstratos e virtuais
Uma interface pode declarar static abstract membros e static virtual para todos os tipos de membros, exceto campos. Ao declarar estes membros, uma interface pode exigir que os tipos de implementação definam operadores ou outros membros estáticos. Esse recurso permite que algoritmos genéricos especifiquem um comportamento semelhante a um número. Você pode ver exemplos nos tipos numéricos no tempo de execução do .NET, como System.Numerics.INumber<TSelf>. Estas interfaces definem operadores matemáticos comuns implementados por muitos tipos numéricos. O compilador deve resolver chamadas e static virtual métodos em static abstract tempo de compilação. Os static virtual métodos e static abstract declarados em interfaces não têm um mecanismo de despacho de tempo de execução análogo ou virtualabstract métodos declarados em classes. Em vez disso, o compilador usa informações de tipo disponíveis em tempo de compilação. Portanto, static virtual os métodos são quase exclusivamente declarados em interfaces genéricas. Além disso, a maioria das interfaces que declaram static virtual ou static abstract métodos declaram que um dos parâmetros de tipo deve implementar a interface declarada. Por exemplo, a INumber<T> interface declara que T deve implementar INumber<T>. O compilador usa o argumento type para resolver chamadas para os métodos e operadores declarados na declaração de interface. Por exemplo, o int tipo implementa INumber<int>. Quando o parâmetro T type indica o argumento inttype , os membros declarados static em int são invocados. Como alternativa, quando double é o argumento type, os membros declarados staticdouble no tipo são invocados.
Importante
O despacho de métodos para static abstract e static virtual métodos declarados nas interfaces é resolvido usando o tipo de expressão em tempo de compilação. Se o tipo de execução de uma expressão for derivado de um tipo diferente em tempo de compilação, são chamados os métodos estáticos no tipo base (tempo de compilação).
Você pode tentar esse recurso trabalhando com o tutorial sobre membros abstratos estáticos em interfaces.
Herança de interface
As interfaces não podem conter o estado da instância. Embora os campos estáticos agora sejam permitidos, os campos de instância não são permitidos nas interfaces.
As propriedades automáticas de instância não são suportadas em interfaces, pois elas declarariam implicitamente um campo oculto. Esta regra tem um efeito subtil nas declarações de propriedade. Em uma declaração de interface, o código a seguir não declara uma propriedade implementada automaticamente como em um class ou struct. Em vez disso, ele declara uma propriedade que não tem uma implementação padrão, mas deve ser implementada em qualquer tipo que implemente a interface:
public interface INamed
{
public string Name {get; set;}
}
Uma interface pode herdar de uma ou mais interfaces base. Quando uma interface herda de outra interface, um tipo que implementa a interface derivada deve implementar todos os membros das interfaces base, além dos membros declarados na interface derivada, conforme mostrado no seguinte código:
public interface I1
{
void M1();
}
public interface I2 : I1
{
void M2();
}
public class C : I2
{
// implements I1.M1
public void M1() { }
// implements I2.M2
public void M2() { }
}
Quando uma interface substitui um método implementado em uma interface base, ela deve usar a sintaxe explícita de implementação da interface.
Quando uma lista de tipos base contém uma classe base e interfaces, a classe base deve vir em primeiro lugar na lista.
Uma classe que implementa uma interface pode implementar explicitamente membros dessa interface. Um membro explicitamente implementado não pode ser acessado por meio de uma instância de classe, mas apenas por meio de uma instância da interface. Além disso, os membros da interface padrão só podem ser acessados por meio de uma instância da interface.
Para obter mais informações sobre a implementação de interface explícita, consulte Implementação de interface explícita.
Exemplo de implementação de interface
O exemplo a seguir demonstra a implementação da interface. Neste exemplo, a interface contém a declaração de propriedade e a classe contém a implementação. Qualquer instância de uma classe que implementa tem propriedades IPoint inteiras x e y.
interface IPoint
{
// Property signatures:
int X { get; set; }
int Y { get; set; }
double Distance { get; }
}
class Point : IPoint
{
// Constructor:
public Point(int x, int y)
{
X = x;
Y = y;
}
// Property implementation:
public int X { get; set; }
public int Y { get; set; }
// Property implementation
public double Distance =>
Math.Sqrt(X * X + Y * Y);
}
class MainClass
{
static void PrintPoint(IPoint p)
{
Console.WriteLine("x={0}, y={1}", p.X, p.Y);
}
static void Main()
{
IPoint p = new Point(2, 3);
Console.Write("My Point: ");
PrintPoint(p);
}
}
// Output: My Point: x=2, y=3
Especificação da linguagem C#
Para mais informações, consulte a secção Interfaces da especificação da linguagem C# e a especificação de características para membros abstratos estáticos em interfaces.