Friday, October 22, 2010

L'interface fondamentaux dans .NET

Une interface est similaire à une classe, mais il fournit une spécification plutôt qu'une mise en œuvre de ses membres. Une interface est spéciale de la manière suivante :

Une classe peut implémenter plusieurs interfaces.En revanche, une classe peut hériter de seulement une seule classe.

Membres de l'interface sont implicitement abstraite. En revanche, une classe peut fournir les membres abstraits et membres de béton avec les implémentations.

Les structures peuvent implémenter les interfaces. En revanche, un struct ne peut pas hériter d'une classe.

Une déclaration d'interface est comme une déclaration de classe, mais il ne fournit aucune implémentation pour ses membres, tous ses membres sont implicitement abstraites.Ces membres seront implémentées par les classes et les structures qui implémentent l'interface.Une interface peut contenir seulement des méthodes, des propriétés, des événements et des indexeurs, qui sont noncoincidentally précisément les membres d'une classe qui peut être résumé.

Voici une version légèrement simplifiée de l'interface IEnumerator, définie dans des System.Collections :

public interface IEnumerator
{
BOOL MoveNext().
objet actuel {get;}
}

Membres de l'interface ont l'accessibilité de même que le type d'interface, et ils ne peut pas déclarer un modificateur d'accès.

Mise en œuvre d'une interface signifie fournissant une implémentation publique pour tous ses membres :

compte à rebours de classe interne : IEnumerator
{
int count = 11.
public bool MoveNext() {Retour count--> 0;}
objet public actuel {get {nombre de retour;}}
}

Vous pouvez convertir implicitement un objet à n'importe quelle interface qu'il implémente.Par exemple :

IEnumerator e = Countdown() nouveau ;
tout en (e.MoveNext())
Console.Write (e.Current)./ / 109876543210

Interfaces peuvent dériver d'autres interfaces.Par exemple :

interface publique IUndoable {void Undo();}
interface publique IRedoable : IUndoable {void Redo();}

IRedoable hérite de tous les membres de IUndoable.


Mise en œuvre de plusieurs interfaces peut parfois entraîner lors d'une collision entre les signatures des membres. Vous pouvez résoudre telles collisions en appliquant explicitement un membre d'interface.Prenons l'exemple suivant :

I1 d'interface {void foo();}
l'interface I2 {int foo();}

public class widget : I1, I2
{
public foo() void
{
Console.WriteLine
("Du widget implementation of I1.Foo »).
}

int I2.Foo()
{
Console.WriteLine
("Du widget implementation of I2.Foo »).
retour 42 ;
}
}

Parce que les I1 et I2 ont des signatures de Foo contradictoires, Widget implémente explicitement Foo méthode du I2.Ceci permet aux deux méthodes coexistent dans une seule classe.La seule façon d'appeler un membre explicitement mis en place est d'effectuer un cast à son interface :

Widget w = nouvelle Widget() ;
w.Foo() ;/ / Mise en œuvre du widget de la I1.Foo
((I1)w).Foo() ;/ / Mise en œuvre du widget de la I1.Foo
((I2)w).Foo() ;/ / Mise en œuvre du widget de la I2.Foo

Une autre raison pour implémentez explicitement les membres d'interface est pour masquer les membres qui sont hautement spécialisés et distrayant de cas d'utilisation normale d'un type.Par exemple, un type qui implémente l'interface ISerializable voudrait généralement éviter affichant ses membres ISerializable sauf si expressément coulé à cette interface.


Un membre de l'interface implémentée implicitement est, par défaut, scellé.Il doit être marqué virtuel ou abstraite dans la classe de base pour être substituée.Par exemple :

interface publique IUndoable {void Undo();}

public class TextBox : IUndoable
{
public Undo() void virtuel
{
Console.WriteLine ("TextBox.Undo").
}
}

public class RichTextBox : TextBox
{
public override void Undo()
{
Console.WriteLine ("RichTextBox.Undo").
}
}

Appeler le membre d'interface par le biais de la classe de base ou de l'interface appelle mise en œuvre de la sous-classe :

RichTextBox r = nouvelle RichTextBox() ;
r.Undo() ;/ / RichTextBox.Undo
((IUndoable)r).Undo() ;/ / RichTextBox.Undo
((TextBox)r).Undo() ;/ / RichTextBox.Undo

Un membre d'interface explicite mis en œuvre ne peut pas être marqué virtuel, ni peut être substituée de la manière habituelle.Il peut, cependant, être remis sur pied.

Une sous-classe peut implémenter de nouveau un membre d'interface déjà implémenté par une classe de base.Nouvelle implémentation détourne une implémentation de membre (lorsqu'il est appelé par le biais de l'interface) et fonctionne si le membre est virtuel dans la classe de base ou non.Il collabore en outre si un membre est implémenté implicitement ou explicitement — même si elle fonctionne mieux dans ce dernier cas, comme nous démontrerons.

Dans l'exemple suivant, TextBox implémente explicitement IUndo.Undo, donc il ne peut pas être marqué comme virtuel.« Substituer » il, RichTextBox doit implémenter méthode Undo du IUndo :

interface publique IUndoable {void Undo();}

public class TextBox : IUndoable
{
VOID IUndoable.Undo()
{Console.WriteLine ("TextBox.Undo");}
}

public class RichTextBox : TextBox, IUndoable
{
public Undo() void nouveau
{Console.WriteLine ("RichTextBox.Undo");}
}

Appeler le membre reimplemented via les appels de l'interface de mise en œuvre de la sous-classe :

RichTextBox r = nouvelle RichTextBox() ;
r.Undo() ;/ / RichTextBox.Undo Case 1
((IUndoable)r).Undo() ;/ / RichTextBox.Undo Case 2

En supposant que la même définition de RichTextBox, supposons maintenant que TextBox mis en œuvre Undoimplicitly :

public class TextBox : IUndoable
{
public Undo() void
{Console.WriteLine ("TextBox.Undo");}
}

Cela donnerait nous une autre façon d'appeler Undo, qui serait « casser » du système, comme le montre l'affaire 3 :

RichTextBox r = nouvelle RichTextBox() ;
r.Undo() ;/ / RichTextBox.Undo Case 1
((IUndoable)r).Undo() ;/ / RichTextBox.Undo Case 2
((TextBox)r).Undo() ;/ / TextBox.Undo Case 3

Cas 3 montre que nouvelle implémentation détournement est efficace seulement lorsque lorsque un membre est appelé à via l'interface et non par la classe de base.C'est habituellement indésirable comme il peut signifier la sémantique incompatible, rendant la réimplémentation plus appropriée pour la substitution de membres de l'interface implémentée explicitement.

No comments:

Post a Comment