2009-03-27 9 views

Respuesta

83

Porque una interfaz describe el comportamiento. Los constructores no son comportamiento. Cómo se construye un objeto es un detalle de implementación.

+21

Creo que está poniendo demasiado significado a la implementación de un detalle: un constructor en .NET es en realidad un método que se llama inmediatamente después de que se crea el objeto (asignado en la memoria). No hay ninguna razón por la que no pueda definirse como comportamiento también. Por supuesto, las implementaciones también pueden declarar libremente otros constructores, del mismo modo que pueden sobrecargar un método que implemente una interfaz. Los constructores en las interfaces serían una característica poco utilizada, pero no inútil. – EMP

+0

Creo que el objetivo de la pregunta es: ya que está construido de esta manera, ¿cuál es la mejor práctica? Entonces supongo que la respuesta es: usando clases abstractas, como dice esta respuesta: http://stackoverflow.com/a/2804067/1181162 – Vince

0

Debido a que no se puede crear una instancia de una interfaz, por lo que una construcción tiene sentido.

+5

¿Cómo tienen sentido las clases abstractas? – Indrek

28

¿Cómo llamarías al constructor? Cuando utiliza interfaces, normalmente pasa una instancia de la interfaz (o más bien, una referencia). También tenga en cuenta que si una clase implementa una interfaz, una clase derivada hereda esa interfaz, pero puede no tener el mismo conjunto de constructores.

Ahora, puedo ver el uso de lo que llamo las interfaces estáticas para la especificación de los constructores y otros miembros esencialmente estáticos para su uso en métodos genéricos. Ver my blog post on the idea para más información.

+0

+1 Creo que esto sería una gran adición a .NET y he actualizado el elemento de comentarios de Connect asociado: https://connect.microsoft.com/VisualStudio/feedback/details/412848/allow-structural-type-constraints -for-generic-type-parameters – EMP

+0

Puedo pensar en tres características de clase de interfaces: (1) implementaciones predeterminadas para métodos o propiedades (tenga en cuenta que las interfaces heredadas no podrían sobrescribir las de la base); (2) permitiendo que el mismo identificador duplique efectivamente como una interfaz y una clase estática; (3) definir un método estático para usar cuando se llama "nuevo" en la interfaz. Tenga en cuenta que los números 2 y 3 serían azúcar sintáctica, pero creo que podrían aclarar algunas cosas. Si .net era compatible con # 1, las interfaces podrían tener nuevos métodos o propiedades añadidas sin romper las implementaciones existentes. – supercat

+0

@supercat: Sí, he estado pensando en 1 por un tiempo también, y también lo ha estado en MS, creo. Hay una entrevista con Vance Morrison donde habla sobre esto. –

9

No, no puede haber constructores en las interfaces por los motivos que se han publicado. Sin embargo, puedes en clases abstractas. Digamos, por ejemplo, que tienes esta clase base.

public abstract class ClassOne 
{ 
    protected int _x; 
    protected string _s; 

    public ClassOne(int x, string s) 
    { 
     _x = x; 
     _s = s; 
    }   
} 

Note que no hay constructores que no toma ningún argumento (constructor por defecto) lo que significa cualquier clase que hereda de ClassOne deben llamar al constructor que tiene 2 argumentos.

Esto no es válido y no se compilará.

public class ClassTwo : ClassOne 
{ 
    public ClassTwo() 
    { } 
} 

Sin embargo, esto es válido y compilará.

public class ClassTwo : ClassOne 
{ 
    public ClassTwo(int x, string s) : base(x, s) 
    { } 
} 

Me gustaría señalar aquí que en C# solo se puede heredar de una clase base. Lo que significa que esta puede no ser la solución correcta para una situación particular, pero es algo en lo que pensar.

Tony.

+0

Como las clases no pueden heredar constructores, creo que esto es solo una solución parcial porque requiere la subclase implementar su llamada de constructor de una manera especial, pero no garantiza que la subclase tenga un constructor con la misma firma. –

9

Entre todas las demás razones ya publicadas, tenga en cuenta que una clase puede implementar fácilmente varias interfaces; ¿Qué constructor debería usarse entonces?

+1

Hay una sintaxis perfecta para implementar métodos de interfaz con la misma firma que podría usarse para los constructores. – Simon

+0

No estoy seguro de haber entendido (quizás no): quise decir que la clase A puede implementar interfaces IAlpha con un constructor sin argumentos, IBeta con un constructor con un argumento e IGamma con un constructor con dos argumentos: ¿Qué constructor debería implementar la clase A? –

+0

Ah, esta es la única respuesta que realmente tiene sentido para mí.Todos los argumentos de que no se puede crear una instancia de una interfaz me dejan preguntando "¿Y qué?" El objetivo de una interfaz es declarar que tal y tal conjunto de funciones debe implementarse en cualquier clase que presuma implementar la interfaz. Parece razonable decir que una clase así también debería tener que implementar un constructor que tome este conjunto particular de argumentos. Pero el argumento de constructores enfrentados, ahora que presenta un problema. – Jay

6

Otras respuestas ya han señalado por qué no tiene sentido tener una declaración de constructor en una interfaz. Pero de su pregunta, supongo que probablemente esté buscando el abstract factory pattern.

Para dar un ejemplo basado en su pregunta: usted dice que le gustaría declarar de alguna manera que un 'motor' debe pasarse al constructor.Usted puede hacer esto al declarar una interfaz independiente para un servicio de la construcción de esta manera:

public interface IGadgetFactory 
{ 
    IGadget CreateGadget(Engine engine); 
} 

Cualquier código que debe crear IGadget casos puede entonces utilizar una instancia IGadgetFactory en lugar de llamar directamente a ningún constructor.

0

Además de las otras explicaciones que se dan aquí, tendría que inventar una nueva sintaxis para llamar de todos modos, ya que si usted tiene dos o más implementaciones de perímetro en la línea de:

Dim x as new IDoStuff() 

aplicación Whice se llama ?

+0

Si estuviera diseñando un lenguaje, permitiría que una interfaz nombrara un método estático para ser utilizado, por lo que la declaración anterior sería equivalente a, p. 'Dim X As IDoStuff = IDoStuff_Creator.CreateNew();' – supercat

Cuestiones relacionadas