2010-01-29 18 views
8

Soy nuevo en OOP y tengo algunas preguntas.Interfaz en C#

  1. ¿Por qué los métodos declarados en una interfaz no tienen modificadores (públicos, privados, etc.)?

  2. En este código:

class Program 
{ 
    static void Main(string[] args) 
    { 
     X ob = new Y(); 
     ob.add(4, 5); 
     Z ob1 = new Y(); 
     ob1.mull(2, 3); 
     Console.Read(); 
    } 
} 

public interface X 
{ 
    void add(int x, int y); 
} 
public interface Z 
{ 
    void mull(int x, int y); 
} 

class Y : X, Z 
{ 
    void X.add(int x, int y)//here we are not decalring it as public ,why? 
    { 
     Console.WriteLine("sum of X and y is " + (x + y)); 
    } 
    void Z.mull(int x, int y) 
    { 
     Console.WriteLine("product of X and Y is" + (x * y)); 
    } 
} 

Ambos métodos no requieren modificadores pero cuando yo no uso la interfaz, como X.add() arriba, tienen que hacer pública la aplicación. ¿Por qué?

+0

posible duplicado de http://stackoverflow.com/questions/1652123/is-there-a-reason-you-can-not-define-the-access-modifier-on-a-method-or-in- an-int –

Respuesta

1

Porque los miembros de la interfaz son automáticamente públicos. Está definiendo un contrato a través de una interfaz, y no tendría sentido que los miembros no sean públicos, ya que debe implementarlos en su clase de implementación.

34

Una interfaz es un contrato. Dice "Puedo hacer estas cosas". ¿De qué sirve que alguien le entregue una instancia de IInterface en la que no puede usar algunos de los métodos de ese contrato porque no se han marcado como públicos?

Esta es la razón fundamental para diseñar el lenguaje de esta manera. La especificación para esto está en §13.2 de la especificación de idioma:

Todos los miembros de la interfaz tienen acceso público implícitamente. Es un error de tiempo de compilación para las declaraciones de los miembros de la interfaz para incluir cualquier modificador. En particular, los miembros de las interfaces no pueden ser declarados con los modificadores abstract, public, protected, internal, private,virtual, override o static.

En cuanto a su código, este es un ejemplo de explicit interface implementation. Es más útil cuando una clase o estructura implementa dos interfaces, cada una con un miembro con la misma firma. Por ejemplo, tanto IEnumerable como IEnumerable<T> definen un método GetEnumerator que no acepta parámetros.

public interface IEnumerable { 
    IEnumerator GetEnumerator(); 
} 

public interface IEnumerable<T> : IEnumerable { 
    IEnumerator<T> GetEnumerator(); 
} 

Tenga en cuenta que por las definiciones anteriores, cualquier clase que implemente IEnumerable<T> también debe implementar IEnumerable. Tenga en cuenta que el tipo de devolución no forma parte de la firma y, por lo tanto, tenemos un conflicto con IEnumerable.GetEnumerator y IEnumerable<T>.GetEnumerator. Esto es lo que la implementación de interfaz explícita está destinado a resolver:

class X<T> : IEnumerable<T> { 
    List<T> _list = new List<T>(); 
    public IEnumerator<T> GetEnumerator() { 
     return _list.GetEnumerator(); 
    } 

    IEnumerator GetEnumerator() { 
     return GetEnumerator(); // invokes IEnumerable<T>.GetEnumerator 
    } 
} 

miembros que son implementaciones de interfaces explícitas son accesibles solamente a través de una instancia de la interfaz. Por lo tanto:

X<int> x = new X<int>(); 
var e1 = x.GetEnumerator(); // invokes IEnumerable<int>.GetEnumerator 
          // IEnumerable.GetEnumerator is not visible 
IEnumerable y = x; 
var e2 = y.GetEnumerator(); // invokes IEnumerable.GetEnumerator 

Por lo tanto, en el código

X ob = new Y(); 
ob.add(1, 2); // X.add is visible through interface 
Y y = new Y(); 
y.add(1, 2); // compile-time error, X.add is not visible 

Ambos métodos no requieren modificadores pero cuando yo no uso la interfaz, como X.add() anterior, que necesitan hacer pública la implementación. ¿Por qué?

De acuerdo, no está claro exactamente lo que está preguntando aquí. Los modificadores de acceso no están permitidos para implementaciones de interfaz explícitas. Esto es de 13,4:

Se trata de un error en tiempo de compilación para una implementación explícita miembro de interfaz para incluir modificadores de acceso, y es un error en tiempo de compilación para incluir los modificadores abstract, virtual, override o static.

Si una implementación de interfaz no está marcada como una implementación de interfaz explícita, entonces debe tener el modificador de acceso public. Esto es 13.4.4 (mapeo Interface):

mapeo de interfaz para una clase o estructura C localiza una implementación para cada miembro de cada interfaz especificada en la lista de clase base de C. La implementación de un miembro de interfaz particular I.M, donde I es la interfaz en la que se declara el miembro de M, se determina mediante el examen de cada clase o struct S, comenzando con C y repitiendo para cada clase base sucesiva de C, hasta que un partido se encuentra

  • Si S contiene una declaración de un miembro de aplicación de interfaz explícita que coincide con I y M, entonces esta persona es la implementación de I.M

  • De lo contrario, si S contiene una declaración de un miembro público no estático que coincide con M, este miembro es la implementación de I.M.

Un error de tiempo de compilación se produce si implementaciones no pueden ser localizados para todos los miembros de todas las interfaces especificadas en la lista de la clase base de C.

Así que, en resumen, el compilador busca primero una implementación de interfaz explícita. Si no puede encontrar uno, busca un miembro público no estático, con la misma firma que el método M que se está implementando. Si no puede encontrar uno, se produce un error en tiempo de compilación. Entonces las reglas son esto.Para implementar un miembro de interfaz I.M:

  1. Si implementa I.M explícitamente a continuación, la sintaxis es

    return-type I.M(parameter-list)

  2. De lo contrario, la sintaxis es

    public return-type M(parameter-list)

Por lo tanto, la

podemos implementar de forma explícita:

class Explicit : IAdd { 
    int IAdd.Add(int x, int y) { return x + y; } 
} 

o no:

class NotExplicit : IAdd { 
    public int Add(int x, int y) { return x + y; } 
} 

La diferencia es entonces que Explicit.Add no es visible a menos casos de Explicit se escriben como IAdd :

IAdd explicitInterface = new Explicit(); 
explicitInterface.Add(2, 2); 
Explicit explicit = new Explicit(); 
explicit.Add(2, 2); // compile-time error 

mientras que

IAdd notExplicitInterface = new NotExplicit(); 
notExplicitInterface.Add(2, 2); 
NotExplicit notExplicit = new NotExplicit(); 
notExplicit.Add(2, 2); // okay, NOT a compile-time error as above 

ayuda eso?

+6

Esta respuesta es completamente completa. –

+0

Tiene que haber algo que falta en su respuesta corta. Todavía lo estoy buscando ... –

1

Directamente desde Microsoft: "Los miembros de interfaz son siempre públicos porque el propósito de una interfaz es permitir que otros tipos de acceso una clase o estructura ".

+0

Es posible que desee corregir sus enlaces. –

+0

Esto ha sido arreglado, thx. – alchemical

0

Porque las funciones, los campos declarados en la interfaz tienen siempre el modificador público por defecto. Por lo tanto, al implementarlo, no tiene que tipear public porque el método class now now es la implementación de la interfaz por lo que es público. En las clases, todos los campos y métodos son privados, pero fallan.

1

Dado que sus dos interfaces no definen métodos con la misma firma, no necesita implementación explícita. Se podría hacer lo siguiente:

public void add(int x, int y) 
{ 
    Console.WriteLine("sum of X and y is " + (x + y)); 
} 
public void mull(int x, int y) 
{ 
    Console.WriteLine("product of X and Y is" + (x * y)); 
} 

Esa es la implementación de una interfaz implícita, y ahora es más fácil llamar a esos métodos en una instancia de la clase. Simplemente llame al myInstance.add(1, 2) en lugar de tener que enviar myInstance para que sea una instancia de la interfaz X.

0

Esta es la diferencia entre una implementación de una interfaz Explict y Implict.

Normalmente querrá implementar una interfaz implícitamente, lo que significa que los miembros implementados están disponibles públicamente. Esto tiene sentido si se tiene en cuenta que la implementación de una interfaz generalmente representa que una clase puede realizar una función dada (como ser eliminada a través de IDisposable).

En situaciones en las que necesita un tipo para implementar una interfaz pero no desea que esos miembros de la interfaz sean públicamente accesibles, utilice una implementación explícita. Los miembros siguen siendo accesibles, pero solo cuando se hace referencia al tipo a través de la interfaz.

1

Voy a hacer una copia de seguridad y explicar los síntomas que está informando en lugar de tratar de explicar por qué el modificador público es innecesario; las otras respuestas lo han explicado adecuadamente.

Probablemente la razón por la que está confundido es porque está utilizando una implementación de interfaz explícita. Cuando utiliza implementación de interfaz explícita, debe convertir la instancia de objeto a ese tipo de interfaz antes de poder llamar a sus métodos.

Si elimina la "X". desde su implementación X.Add, podrá "ver" y usar la interfaz sin el molde explícito. Esta es la implementación de la interfaz "implícita". Siempre que no tenga colisiones de nombres, o alguna razón para hacer que los miembros de la interfaz sean menos visibles para los clientes normales, es probable que prefiera la implementación implícita de la interfaz.