Por ejemplo, supongamos que quiero una interfaz ICar
y que todas las implementaciones contendrán el campo Year
. ¿Esto significa que cada implementación tiene que declarar por separado Year
? ¿No sería mejor simplemente definir esto en la interfaz?¿Por qué las interfaces C# no pueden contener campos?
Respuesta
Aunque muchas de las otras respuestas son correctas en el nivel semántico, me parece interesante abordar también este tipo de preguntas desde el nivel de detalles de la implementación.
Una interfaz puede ser pensado como una colección de ranuras, que contienen métodos. Cuando una clase implementa una interfaz, se requiere que la clase le diga al tiempo de ejecución cómo completar todos los espacios requeridos. Cuando usted dice
interface IFoo { void M(); }
class Foo : IFoo { public void M() { ... } }
la clase dice "cuando se crea una instancia de mí, cosas de una referencia a Foo.M en la ranura para IFoo.M.
A continuación, cuando se hace una llamada:
IFoo ifoo = new Foo();
ifoo.M();
el compilador genera un código que dice "pregunte al objeto qué método está en la ranura para IFoo.M, y llame a ese método.
Si una interfaz es una colección de ranuras que contienen métodos, algunas de esas ranuras también pueden contener los métodos get y set de una propiedad, los métodos get y set de un indexador, y los métodos add y remove de un evento. Pero un campo no es un método. No hay una "ranura" asociada a un campo que luego pueda "completar" con una referencia a la ubicación del campo. Y, por lo tanto, las interfaces pueden definir métodos, propiedades, indizadores y eventos, pero no campos.
Lo que a veces echo de menos es una capacidad similar a la de Java para definir constantes de nivel de interfaz, que presumiblemente no requerirían un "espacio" para admitir en el idioma. – LBushkin
Me gusta la explicación en palabras simples. Gracias. "CLR via C#" y "Essential .net volume 1" proporcionan más detalles. –
¿Por qué un campo no tiene ranura? y la misma pregunta con los operadores? Recuerdo haber escuchado sobre el tipado de pato utilizando la reflexión para ver si se implementaba una interfaz, incluso si la clase no heredaba la interfaz. ¿Por qué no se puede usar el reflejo (o una ranura) para levantar un campo? Todavía estoy escribiendo mi código por lo que es posible que no necesite/desee campos, pero me sorprendió descubrir que no puedo usar operadores. los operadores son exactamente como los métodos de mi comprensión, excepto que no todos pueden sobrecargarse ('Una interfaz no puede contener constantes, campos, operadores'. De http://msdn.microsoft.com/en-us/library/ms173156.aspx) –
¿Por qué no tienen una propiedad Year
, que está perfectamente bien?
Las interfaces no contienen campos porque los campos representan una implementación específica de representación de datos, y exponerlos rompería la encapsulación. Por lo tanto, tener una interfaz con un campo codificaría efectivamente una implementación en lugar de una interfaz, ¡lo cual es una curiosa paradoja para una interfaz!
Por ejemplo, parte de su especificación Year
podría requerir que sea válido para ICar
ejecutores para permitir la asignación a una Year
que es más tarde que el actual año + 1 o antes de 1900. No hay manera de decir que si había expuesto Year
campos - es mejor utilizar las propiedades en su lugar para hacer el trabajo aquí.
Para esto puede tener una clase base de automóvil que implemente el campo de año, y todas las demás implementaciones pueden heredar de ella.
Las interfaces en C# están destinadas a definir el contrato que una clase cumplirá, no una implementación en particular.
En ese espíritu, C# interfaces de PERMITEN propiedades que se definen - que el llamante debe suministrar una implementación para:
interface ICar
{
int Year { get; set; }
}
clases que implementan pueden utilizar auto-propiedades para simplificar la implementación, si no hay lógica especial asociada con la propiedad:
class Automobile : ICar
{
public int Year { get; set; } // automatically implemented
}
No es todo lo que es público como parte del contrato. Si una clase tiene un año público, ¿no dice que el contrato de clase tiene un campo de tipo Año para estar presente y accesible? –
Tarde para la fiesta, pero no, en este caso significa que el contrato tiene un PROPIEDAD Año que se supone que debe implementar cualquier clase permanente. Las propiedades son en realidad métodos get/set, que tienen un campo de respaldo generado automáticamente si no se necesita una lógica especial. La sintaxis especial es solo para una notación más clara. – user3613916
¿Cómo puedo definir un valor predeterminado constante (como 123) para esa implementación automática de 'Año'? – lama12345
La respuesta corta es sí, cada tipo de implementación tendrá que crear su propia variable de respaldo. Esto se debe a que una interfaz es análoga a un contrato. Todo lo que puede hacer es especificar trozos de código accesibles al público que un tipo de implementación debe poner a disposición; no puede contener ningún código en sí mismo.
Considere este escenario usando lo que ha sugerido:
public interface InterfaceOne
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public interface InterfaceTwo
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public class MyClass : InterfaceOne, InterfaceTwo { }
Tenemos un par de problemas aquí:
- Debido a que todos los miembros de una interfaz son - por definición - pública, nuestro respaldo la variable ahora está expuesta a cualquiera que use la interfaz
- ¿Cuál
myBackingVariable
usaráMyClass
?
El enfoque más común es declarar la interfaz y una clase abstracta de barebones que la implementa. Esto le permite la flexibilidad de heredar de la clase abstracta y obtener la implementación de forma gratuita, o implementar explícitamente la interfaz y poder heredar de otra clase.Funciona de la siguiente manera:
public interface IMyInterface
{
int MyProperty { get; set; }
}
public abstract class MyInterfaceBase : IMyInterface
{
int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
}
Las interfaces no incluyen ninguna implementación.
- Definir una interfaz con una propiedad.
- Además puede implementar esa interfaz en cualquier clase y usar esta clase en el futuro.
- Si es necesario, puede tener esta propiedad definida como virtual en la clase para que pueda modificar su comportamiento.
Una interfaz define propiedades y métodos de instancia públicas. Los campos suelen ser privados, o en el más protegido, internos o protegidos internos (el término "campo" no suele utilizarse para nada público).
Según lo declarado por otras respuestas, puede definir una clase base y definir una propiedad protegida a la que todos los herederos puedan acceder.
Una rareza es que una interfaz puede de hecho definirse como interna pero limita la utilidad de la interfaz, y normalmente se usa para definir la funcionalidad interna que no es utilizada por otro código externo.
Eric Lippert lo clavó, usaré una forma diferente de decir lo que dijo. Todos los miembros de una interfaz son virtuales y todos deben ser reemplazados por una clase que hereda la interfaz. No escribe explícitamente la palabra clave virtual en la declaración de interfaz, ni usa la palabra clave override en la clase, están implícitas.
La palabra clave virtual se implementa en .NET con métodos y una tabla v llamada, una matriz de punteros de método. La palabra clave override rellena el espacio de la tabla v con un puntero de método diferente, sobrescribiendo el que produce la clase base.Las propiedades, los eventos y los indexadores se implementan como métodos bajo el capó. Pero los campos no son. Las interfaces, por lo tanto, no pueden contener campos.
Proporcionó el nombre técnico/real (v-table) al concepto de slots mencionado por Eric. Gracias por el detalle Hans. – RBT
Otros han dado el 'Por qué', así que solo agregaré que su interfaz puede definir un Control; si lo envuelve en una propiedad:
public interface IView {
Control Year { get; }
}
public Form : IView {
public Control Year { get { return uxYear; } } //numeric text box or whatever
}
Mucho se ha dicho, pero para hacerlo simple, aquí está mi opinión. Las interfaces están destinadas a tener contratos de método implementados por los consumidores o clases y no tener campos para almacenar valores.
Usted puede argumentar que entonces ¿por qué las propiedades están permitidas? Entonces, la respuesta simple es que las propiedades se definen internamente como solo métodos.
Si necesita acceder a un miembro solo haga una propiedad y estará bien. – Unome
- 1. interfaces no pueden contener campos
- 2. ¿Por qué las variantes de Delphi no pueden contener objetos?
- 3. Java: ¿Pueden las interfaces contener variables constantes definidas en ellas?
- 4. ¿Por qué las cadenas no literales no pueden contener líneas nuevas?
- 5. JAXB No se pueden manejar las interfaces
- 6. ¿Por qué las uniones anónimas no pueden contener miembros con constructores/destructores no triviales?
- 7. ¿Por qué las interfaces no son [Serializable]?
- 8. ¿Por qué las cadenas en $ _POST no pueden contener un punto "."?
- 9. ¿Por qué los campos de clase no pueden ser var?
- 10. La interfaz C# no puede contener operadores
- 11. ¿Qué elementos HTML no pueden contener nodos secundarios?
- 12. ¿Por qué no campos abstractos?
- 13. Por qué las propiedades no son declarables en las interfaces
- 14. ¿Por qué no se pueden inicializar campos no estáticos dentro de las estructuras?
- 15. Las etiquetas de servidor no pueden contener construcciones <% ... %>
- 16. ¿Por qué las estructuras no se pueden asignar directamente?
- 17. ¿Por qué las propiedades no pueden ser de solo lectura?
- 18. ¿Por qué implementamos las interfaces recursivamente?
- 19. ¿Por qué debería crear interfaces en PHP?
- 20. ¿Por qué mis contratos de operación en mi cliente wcf no pueden tomar interfaces como parámetros?
- 21. ¿Pueden las matrices PHP contener elementos de tipos diferentes?
- 22. Importancia de las interfaces C#
- 23. ¿Por qué las enumeraciones no se pueden modificar?
- 24. ¿Por qué las clases internas no pueden declarar miembros estáticos?
- 25. ¿Por qué no se pueden compartir las variables miembro?
- 26. ¿Por qué las interfaces genéricas no son co/contravariantes por defecto?
- 27. ¿Se pueden aplicar métodos de extensión a las interfaces?
- 28. ¿Cómo dividir csv cuyas columnas pueden contener,
- 29. ¿Por qué crear clases e interfaces abstractas?
- 30. ¿Por qué las clases de Java no heredan las anotaciones de las interfaces implementadas?
Las interfaces no tienen implementación, para esto usan una clase abstracta, con la propiedad Año – PostMan
Para agregar a lo que se ha dicho aquí, las interfaces son contratos, y un campo es un detalle de implementación en que define una ranura en la memoria de la máquina para poner un valor (ya sea escalar o puntero de dirección) en. – herzmeister
Pero si el campo es público, es parte del contrato y no solo un detalle de implementación, ¿verdad? – Alex