Access to Interface members
The invocation of the interface method and the rules that take the index indicator access are the same as in the class. If the name of the underlying member is consistent with the inherited top-level member, the underlying member overrides the high-level member with the same name. However, because the interface supports multiple inheritance, in multi-inheritance, if two parent interfaces contain members of the same name, this results in two semantics (which is one of the reasons why the multi-inheritance mechanism of classes is removed in C #), which needs to be explicitly defined:
Using System;
Interface Isequence {
int Count {get; set;}
}
Interface IRing {
void Count (int i);
}
Interface Iringsequence:isequence, IRing {}
Class CTest {
void Test (Iringsequence rs) {
Rs. Count (1); Error, Count has two semantics
Rs. Count = 1; Error, Count has two semantics
((isequence) RS). Count = 1; That's right
((IRing) RS). Count (1); Call Iring.count correctly
}
}
In the above example, the first two statements are Rs. Count (1) and Rs. Count = 1 Produces a two ambiguity, resulting in a compile-time error, so you must explicitly assign the parent interface type to RS, which does not incur additional overhead at run time.
Let's look at the following example:
Using System;
Interface Iinteger {
void Add (int i);
}
Interface Idouble {
void Add (double D);
}
Interface Inumber:iinteger, idouble {}
Class Cmytest {
void Test (Inumber Num) {
Num.add (1); Error
Num.add (1.0); That's right
((Iinteger) n). ADD (1); That's right
((idouble) n). ADD (1); That's right
}
}
Calling Num.add (1) causes two semantics because the parameter types of the candidate overloaded methods apply. However, calling Num.add (1.0) is allowed because 1.0 is inconsistent with the parameter type of the method Iinteger.add (), and only idouble.add is applicable. However, as long as the explicit assignment is added, it will never produce two semantics.
Problems with the multiple inheritance of interfaces can also lead to problems on member access. For example:
Interface IBase {
void Fway (int i);
}
Interface Ileft:ibase {
new void Fway (int i);
}
Interface Iright:ibase
{void G ();}
Interface Iderived:ileft, IRight {}
Class CTest {
void Test (iderived d) {
D. Fway (1); Call ILeft. Fway
((IBase) d). Fway (1); Call IBase. Fway
((ILeft) d). Fway (1); Call ILeft. Fway
((IRight) d). Fway (1); Call IBase. Fway
}
}
In the example above, the method Ibase.fway is overridden by the ILeft member method Fway in the derived interface ILeft. So to D. The invocation of Fway (1) is actually called. Although the Ileft.fway method is not overwritten from the inheritance path of ibase-> iright-> iderived. We just need to remember this: once a member is overwritten, all access to it is "intercepted" by the member who overwrites it.
Class-To-interface implementations
As we have said earlier, the interface definition does not include the implementation part of the method. Interfaces can be implemented through classes or structs. We mainly talk about implementing interfaces through classes. When you implement an interface with a class, the name of the interface must be included in the list of base classes in the class definition.
The following example shows an example of an interface implemented by a class. Where isequence is a queue interface that provides a member method for adding objects to the end of the queue, add (), IRing as a looping table interface, provides a way to insert objects into the ring (object obj), and the method returns the inserted position. The class Ringsquence implements interface Isequence and interface iring.
Using System;
Interface Isequence {
Object Add ();
}
Interface Isequence {
Object Add ();
}
Interface IRing {
int Insert (object obj);
}
Class Ringsequence:isequence, IRing
{
public Object Add () {...}
public int Insert (object obj) {...}
}
If a class implements an interface, the class implicitly inherits all the parent interfaces of that interface, regardless of whether the parent interfaces are listed in the base class table of the class definition. Look at the following example:
Using System;
Interface IControl {
void Paint ();
}
Interface Itextbox:icontrol {
void SetText (string text);
}
Interface Ilistbox:icontrol {
void Setitems (string[] items);
}
Interface Icombobox:itextbox, IListBox {}
Here, the interface IComboBox inherits ITextBox and IListBox. The class TextBox not only implements the interface ITextBox, but also implements the parent interface icontrol of the interface ITextBox.
As we have seen earlier, a class can implement multiple interfaces. Let's look at the following example:
Interface IDataBound {
void Bind (Binder b);
}
public class Editbox:control, IControl, IDataBound {
public void Paint ();
public void Bind (Binder b) {...}
}
The class EditBox derives from the class control and implements the IControl and IDataBound. In the previous example, the Paint method in interface IControl and the Bind method in the IDataBound interface are implemented with public members in class EditBox. C # provides a choice of ways to implement these methods so that the classes that execute them will avoid making these members public. Interface members can be implemented with a valid name. For example, class EditBox can be changed to methods IControl.Paint and idatabound.bind to implement.
public class Editbox:icontrol, IDataBound {
void IControl.Paint () {...}
void IDataBound.Bind (Binder b) {...}
}
Because each member is implemented by an externally assigned interface member, the members implemented in this way are called external interface members. External interface members can be called only through an interface. For example, the implementation of editbox in the paint method can be invoked simply by creating an IControl interface.
Class Test {
static void Main () {
EditBox editbox = new EditBox ();
EditBox. Paint (); Error: EditBox No Paint event
IControl control = EditBox;
Control. Paint (); Call EditBox's Paint event
}
}
In the above example, the class EditBox inherits from the control class and implements both the IControl and IDataBound interfaces. The paint method in EditBox comes from the IControl interface, and the Bind method comes from the IDataBound interface, both of which are implemented as public members in the EditBox class. Of course, in C # we can also choose not to implement interfaces as public members.
If each member clearly points to the implemented interface, the interface implemented by this means is called an explicit interface member (explicit interface member). In this way we rewrite the example above:
public class Editbox:icontrol, IDataBound {
void IControl.Paint () {...}
void IDataBound.Bind (Binder b) {...}
}
Explicit interface members can only be called through an interface. For example:
Class CTest {
static void Main () {
EditBox editbox = new EditBox ();
EditBox. Paint (); Error: Different methods
IControl control = EditBox;
Control. Paint (); Call EditBox's Paint method
}
}
The above code is for EditBox. The call to Paint () is wrong because EditBox itself does not provide this method. Control. Paint () is the correct way to call.
Note: The interface itself does not provide an implementation of the defined member, it merely illustrates those members that must rely on the support of the class or other interface that implements the interface.
Knowing how to access the interface, we also need to know how to implement the interface, to implement the C # interface, see the next section-implementation interface
C # Interface Basics Tutorial Four access interfaces