Pregunta

¿Cuál es el argumento en contra de declarar protegido de acceso a los miembros de las interfaces?Este, por ejemplo, no es válido:

public interface IOrange
{
    public OrangePeel Peel { get; }
    protected OrangePips Seeds { get; }
}

En este ejemplo, la interfaz de IOrange sería garantía de que los ejecutores al menos proporcionar una OrangePips ejemplo a sus herederos.Si el implementador quisieran, podrían ampliar el alcance completo public:

public class NavelOrange : IOrange
{
    public OrangePeel Peel { get { return new OrangePeel(); } }
    protected OrangePips Seeds { get { return null; } }
}

public class ValenciaOrange : IOrange
{
    public OrangePeel Peel { get { return new OrangePeel(); } }
    public OrangePips Seeds { get { return new OrangePips(6); } }
}

La intención de protected los miembros de las interfaces es proporcionar un contrato de asistencia para herederos (sub-clases), por ejemplo:

public class SpecialNavelOrange : NavelOrange
{
    ...
    // Having a seed value is useful to me.
    OrangePips seeds = this.Seeds; 
    ...
}

(Hay que reconocer que esto no iba a funcionar para structs)

Yo no puede ver mucho de un caso de private o internal modificadores en las interfaces, pero el apoyo tanto de public y protected modificadores parece perfectamente razonable.


Voy a tratar de explicar la utilidad de protected los miembros de interfaces por que los separa de interfaces completo:

Vamos a imaginar una nueva palabra clave de C#, support, para cumplir heredero de los contratos, por lo que declaramos las cosas de la siguiente manera:

public support IOrangeSupport
{
    OrangePips Seeds { get; }
}

Esto haría que nos permite contrato de clases para proporcionar a los miembros protegidos a sus herederos:

public class NavelOrange : IOrange, IOrangeSupport
{
    public OrangePeel Peel { get { return new OrangePeel(); } }
    protected OrangePips Seeds { get { return null; } }
}

Esto no es particularmente útil, ya que las clases ya que implica este contrato por la prestación de los protected los miembros en el primer lugar.

Pero entonces también podríamos hacer esto:

public interface IOrange : IOrangeSupport
{
   ...
}

Aplicando IOrangeSupport a todas las clases que implementan IOrange y de que se les requiera para proporcionar particular protected miembros - que es algo que no podemos en la actualidad.

¿Fue útil?

Solución

Creo que todos martilló el punto de tener una interfaz sólo los miembros públicos, no hay detalles de implementación. Lo que se busca es un clase abstracta .

public interface IOrange
{
    OrangePeel Peel { get; }
}

public abstract class OrangeBase : IOrange
{
    protected OrangeBase() {}
    protected abstract OrangePips Seeds { get; }
    public abstract OrangePeel Peel { get; }
}

public class NavelOrange : OrangeBase
{
    public override OrangePeel Peel { get { return new OrangePeel(); } }
    protected override OrangePips Seeds { get { return null; } }
}

public class ValenciaOrange : OrangeBase
{
    public override OrangePeel Peel { get { return new OrangePeel(); } }
    protected override OrangePips Seeds { get { return new OrangePips(6); } }
}

Edit: Es justo argumentar que si tenemos una PlasticOrange que se deriva de un ornamento de la clase, sólo se puede aplicar IOrange y no el método protegido semillas. Eso está bien. Una interfaz, por definición, es un contrato entre una persona que llama y un objeto, no entre una clase y sus subclases. La clase abstracta es lo más cerca que llegamos a este concepto. Y eso está bien. Lo que están proponiendo es esencialmente otra construcción en el lenguaje a través del cual podemos cambiar las subclases de una clase base a otra sin romper la estructura. Para mí, esto no tiene sentido.

Si va a crear una subclase de una clase, la subclase es una especialización de la clase base. Debe ser plenamente consciente de los miembros protegidos de la clase base. Pero si de repente desea cambiar la clase base a cabo, no tiene sentido que la subclase debería funcionar con cualquier otra IOrange.

I suponga que tiene una buena pregunta, pero parece como un caso límite y no ver ningún beneficio de ella para ser honesto.

Otros consejos

No se puede ver por qué uno desearía esto. Si desea clase derivada para proporcionar una implementación de un método en particular, ir a dar clases base abstractas. Las interfaces son sólo eso - las interfaces. Un contrato público, nada más. Piense en la interfaz como de la especificación que describe cómo debe buscar la aplicación al mundo exterior. Una especificación para un enchufe de dos clavijas no indica (al menos yo supongo que) lo que es la estructura interna debe ser. Simplemente tiene que ser con un enchufe de interfaz compatible. Plug
(fuente: made-in-china.com )

Debido a que no tiene sentido. Una interfaz es un contrato expuesta públicamente. Soy un iThing, por lo tanto, voy a llevar a cabo los métodos iThing si se le pide. No se puede pedir a un iThing confirmar que realiza métodos que no se puede contar.

Existen

Interfaces para permitir a las personas acceder a su clase sin saber cuál es la aplicación concreta. Se divorices por completo la aplicación del contrato de los datos transmitidos.

Por lo tanto, todo en una interfaz debe ser pública. miembros no públicas sólo son útiles si tiene acceso a la aplicación y por lo tanto no contribuyen de manera significativa a una definición de interfaz.

miembros de la interfaz son una API pública; cosas como protected etc, son detalles de implementación - y las interfaces no lo hacen Tienes cualquier aplicación. Sospecho que lo que busca es la implementación de interfaz explícita:

public class NavelOrange : IOrange
{
    public OrangePeel Peel { get { return new OrangePeel(); } }
    OrangePips IOrange.Seeds { get { return null; } }
}

Una interfaz es un contrato que promete cierta funcionalidad a los clientes. En otras palabras, el propósito de una interfaz es ser capaz de lanzar un tipo en él y pasarlo por ahí como que al código que necesita las características garantizadas por esa interfaz. Dado que el código de cliente de un tipo no puede tener acceso a los miembros protegidos de ese tipo, no tiene sentido declarar los elementos protegidos en una interfaz.

Una interfaz es igual la forma de una clave.

introducir descripción de la imagen aquí

No es la clave.

No es el bloqueo.

Es sólo el punto de contacto delgada.

Por esta razón todos los miembros de la interfaz (que define la forma de la llave) debe ser pública.

Para obtener una llave para abrir una cerradura es importante que ambos comparten la misma forma.

Al hacer que la forma (la interfaz) público , puede dejar que otros crean bloqueos compatibles o claves compatibles.

De lo contrario, por lo que es (la interfaz) interno no permitirá que otros para crear bloqueos compatibles o claves compatibles.

Una interfaz es todo acerca de lo que un determinado objeto puede hacer, por lo que cuando se utiliza una clase que implementa la interfaz que el desarrollador esperar que todos los miembros a ser implementadas, por lo que el modificador de acceso protegido no significa nada para las interfaces.

Hay buen criterio en el diseño actual de las interfaces que es que ofrece una mayor flexibilidad ejecutores. Recuerde que muy a menudo las interfaces son escritos por programadores marco y ejecutores son diferentes personas. Para hacer efectiva la aplicación sería innecesariamente duras.

Mediante la implementación de una interfaz del tipo afirma que soporta un conjunto específico de métodos. Si cualquiera de estos métodos no eran públicas, que no estaría disponible para las personas que llaman y por lo tanto el tipo no sería compatible con la interfaz como se ha dicho.

Una interfaz contiene sólo los miembros públicos. Protegido significa lo que usted está declarando solo está disponible para las instancias de la clase y de clase derivada.

Cualquier clase que implementa una interfaz de .NET tendrá que incluir implementaciones de todos los elementos de interfaz. Además, cualquier clase puede exponer a una clase derivada miembros lo desea. Requerir que una implementación de un interfaz debe incluir un elemento que sólo será utilizable a partir de las clases derivadas serviría a ningún propósito útil, a menos que o bien (1) un miembro de este tipo podría ser visible a algo fuera de la interfaz, o (2) implementaciones de interfaz podrían utilizar miembros que no se definen a sí mismos. Si se permitiera interfaces para incluir clases anidadas (que podían acceder a las interfaces' protected miembros), entonces internal elementos de interfaz tendría sentido. De hecho, podrían ser muy útil si una clase anidada dentro de una interfaz podría definir métodos de extensión para esa interfaz. Por desgracia, no existe tal instalación.

BTW, incluso sin ser capaz de clases de nidos en las interfaces, todavía sería útil aplicar un modificador <=> acceso a la interfaz miembros, con el efecto de que sólo el ensamblaje donde se define la interfaz sería capaz de definir cualquier implementaciones para ello.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top