Section 5 interface implementation
1. explicitly implement interface members
To implement the interface, the class can define the explicit interface member execution bodies (explicit interface member implementations ). The explicit interface member execution body can be a method, an attribute, an event, or an index indicator. The definition must be consistent with the full name of the member.
Using system;
Interface icloneable {
Object clone ();
}
Interface icomparable {
Int compareto (object other );
}
Class listentry: icloneable, icomparable {
Object icloneable. Clone (){...}
Int icomparable. compareto (object other ){...}
}
In the above Code, icloneable. Clone and icomparable. compareto are the execution bodies of explicit interface members.
Note:
1. The explicit interface member execution body cannot be accessed through full names in method call, attribute access, and index indicator access. In fact, the execution body of an explicit interface member can only be accessed through the interface instance and only by referencing the interface member name.
2. The execution body of an explicit interface member cannot use any access limiters, and abstract, virtual, override, or static modifiers cannot be added.
3. The explicit interface member execution body has different access methods than other members. Because it cannot be accessed by full name in method call, attribute access, and index indicator access, the explicit interface member execution body is private in a sense. However, they can also be accessed through the instance of the interface, but also have a certain public nature.
4. Only when the class is defined, the interface name is written in the base class list, when the full names, types, and return types defined in the class are exactly the same as the execution bodies of explicit interface members, the execution bodies of explicit interface members are valid. For example:
Class shape: icloneable {
Object icloneable. Clone (){...}
Int icomparable. compareto (object other ){...}
}
An explicit interface member execution body has two purposes:
1. Because the execution body of the explicit interface member cannot be accessed through the instance of the class, the interface implementation part can be separately separated from the public interface. If a class only uses this interface internally, and the class user does not directly use this interface, this explicit interface member execution body can play a role.
2. Explicit interface member execution bodies avoid confusion between interface members due to the same name. If a class wants to adopt different implementation methods for interface members with the same name and return type, it must use the explicit interface member execution body. If there is no explicit interface member execution body, the class cannot be implemented for interface members of different names and return types.
The following definition is invalid because the icomparable interface is not displayed in the base class list during Shape Definition.
Class shape: icloneable
{
Object icloneable. Clone (){...}
}
Class ellipse: Shape
{
Object icloneable. Clone (){...}
}
It is incorrect to define icloneable. clone in ellipse, because even if ellipse implicitly implements the icloneable interface, icloneable still does not explicitly appear in the base class list defined by ellipse.
The full name of an interface member must correspond to the member defined in the interface. In the following example, the execution body of the explicit interface member of Paint must be written as iControl. Paint.
Using system;
Interface iControl
{
Void paint ();
}
Interface itextbox: iControl
{
Void settext (string text );
}
Class textbox: itextbox
{
Void iControl. Paint (){...}
Void itextbox. settext (string text ){...}
}
The class that implements the interface can explicitly implement the members of this interface. When a member is explicitly implemented, the member cannot be accessed through a class instance, but can only be accessed through the instance of this interface. Explicit interface implementation also allows programmers to inherit and share two interfaces with the same member name, and provides a separate implementation for each interface member.
In the following example, the size of the box is displayed in both the metric and imperial units. The box class inherits the ienglishdimensions and imetricdimensions interfaces, which indicate different weights. The two interfaces have the same member name length and width.
Program list 1 demoninterface. CS
Interface ienglishdimensions {
Float length ();
Float width ();
}
Interface imetricdimensions {
Float length ();
Float width ();
}
Class box: ienglishdimensions, imetricdimensions {
Float lengthinches;
Float widthinches;
Public box (float length, float width ){
Lengthinches = length;
Widthinches = width;
}
Float ienglishdimensions. Length (){
Return lengthinches;
}
Float ienglishdimensions. Width (){
Return widthinches;
}
Float imetricdimensions. Length (){
Return lengthinches * 2.54f;
}
Float imetricdimensions. Width (){
Return widthinches * 2.54f;
}
Public static void main (){
// Define an object "mybox "::
Box mybox = new box (30366f, 20366f );
// Define an interface "edimensions "::
Ienglishdimensions edimensions = (ienglishdimensions) mybox;
Imetricdimensions mdimensions = (imetricdimensions) mybox;
// Output:
System. Console. writeline ("length (in): {0}", edimensions. Length ());
System. Console. writeline ("width (in): {0}", edimensions. Width ());
System. Console. writeline ("length (CM): {0}", mdimensions. Length ());
System. Console. writeline ("width (CM): {0}", mdimensions. Width ());
}
}
Output: length (in): 30, width (in): 20, length (CM): 76.2, width (CM): 50.8
Code discussion: If you want to use the English Unit for the default measurement, implement the length and width methods normally, and explicitly implement the length and width methods from the imetricdimensions interface:
Public float length (){
Return lengthinches;
}
Public float width (){
Return widthinches;
}
Float imetricdimensions. Length (){
Return lengthinches * 2.54f;
}
Float imetricdimensions. Width (){
Return widthinches * 2.54f;
}
In this case, you can access the imperial unit from the class instance, and access the metric unit from the interface instance:
System. Console. writeline ("length (in): {0}", mybox. Length ());
System. Console. writeline ("width (in): {0}", mybox. Width ());
System. Console. writeline ("length (CM): {0}", mdimensions. Length ());
System. Console. writeline ("width (CM): {0}", mdimensions. Width ());
2. inherited interface implementation
The interface is immutable, but this does not mean that the interface is no longer evolving. Similar to the inheritance of classes, interfaces can also be inherited and developed.
Note: interface inheritance is different from class inheritance. First, class inheritance not only describes inheritance, but also implements inheritance. interface inheritance only describes inheritance. That is to say, the derived class can inherit the method implementation of the base class, while the derived interface only inherits the description of the member methods of the parent interface, but does not inherit the implementation of the parent interface. Secondly, C # class inheritance only allows single inheritance, but interface inheritance allows multiple inheritance. A subinterface can have multiple parent interfaces.
Interfaces can be inherited from zero or multiple interfaces. When the interface is retransmitted from multiple interfaces, use ":" followed by the inherited interface name, and use "," to separate multiple interface names. The inherited interface should be accessible. For example, inheritance from interfaces of the private or internal type is not allowed. The interface cannot be inherited directly or indirectly from itself. Similar to class inheritance, interface inheritance also forms a hierarchy between interfaces.
See 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 {}
The inheritance of an interface inherits all the members of the interface. In the above example, both the interface itextbox and ilistbox inherit from the interface iControl and inherit the painting method of the interface iControl. The icombobox interface inherits from the itextbox and ilistbox interfaces. Therefore, it should inherit the settext method of the itextbox interface, the setitems method of the ilistbox interface, and the iControl painting method.
A class inherits all the interface implementation programs provided by its basic class.
Without explicitly implementing an interface, a derived class cannot change its interface ing inherited from its basic class in any way. For example
Interface iControl {
Void paint ();
}
Class control: iControl {
Public void paint (){...}
}
Class textbox: Control {
New public void paint (){...}
}
The method paint in textbox hides the method paint in control, but does not change the ing from control. Paint to iControl. Paint. Calling paint through class instances and interface instances will have the following impact:
Control C = new control ();
Textbox T = new Textbox ();
IControl Ic = C;
IControl it = T;
C. Paint (); // affects control. Paint ();
T. Paint (); // the textbox. Paint ();
IC. Paint (); // affects control. Paint ();
It. Paint (); // affects control. Paint ();
However, when an interface method is mapped to a virtual method in a class, the derived class cannot overwrite this virtual method and change the implementation function of the interface. For example, rewrite the preceding statement
Interface iControl {
Void paint ();
}
Class control: iControl {
Public Virtual void paint (){...}
}
Class textbox: Control {
Public override void paint (){...}
}
The following result is displayed:
Control C = new control ();
Textbox T = new Textbox ();
IControl Ic = C;
IControl it = T;
C. Paint (); // affects control. Paint ();
T. Paint (); // the textbox. Paint ();
IC. Paint (); // affects control. Paint ();
It. Paint (); // it affects textbox. Paint ();
Because the explicit interface member implementation program cannot be declared as virtual, it is impossible to overwrite an explicit interface member implementation program. An explicit interface member can call another method to implement the program, and the other method can be declared as virtual so that the derived class can overwrite it. For example:
Interface iControl {
Void paint ();
}
Class control: iControl {
Void iControl. Paint () {paintcontrol ();}
Protected virtual void paintcontrol (){...}
}
Class textbox: Control {
Protected override void paintcontrol (){...}
}
Here, the classes inherited from control can be specialized in the iControl. Paint Implementation Program by overwriting the paintcontrol method.
3. Implement the interface again
We have already introduced that a derived class can overload the member methods defined in the base class. Similar concepts are introduced into class-to-interface implementation, called re-implementation ). Classes inherited from the interface implementation can be re-implemented on the interface. This interface is required to appear in the base class list defined by the class. The re-Implementation of the interface must strictly follow the rules for the first implementation of the interface. The derived interface ing does not affect the interface ing created for the re-Implementation of the interface.
The following code provides an example of interface re-implementation:
Interface iControl {
Void paint ();
Class control: iControl
Void iControl. Paint (){...}
Class mycontrol: control, iControl
Public void paint (){}
}
In fact, control maps iControl. Paint to Control. iControl. paint, but this does not affect the re-implementation in mycontrol. In the re-implementation of mycontrol, iControl. Paint is mapped to mycontrol. Paint.
When the interface is re-implemented, the inherited public member definition and the inherited explicit interface member definition participate in the interface ing process.
Using system;
Interface imethods {
Void F ();
Void g ();
Void H ();
Void I ();
}
Class base: imethods {
Void imethods. F (){}
Void imethods. G (){}
Public void H (){}
Public void I (){}
}
Class derived: Base, imethods {
Public void F (){}
Void imethods. H (){}
}
Here, the implementation of the interface imethods in derived maps the interface methods to derived. F, base. imethods. G, derived. imethods. H, and base. I. As we have mentioned above, when a class implements an interface, it also implicitly implements all the parent interfaces of this interface. Similarly, when a class re-implements an interface, it implicitly re-implements all the parent interfaces of this interface.
Using system;
Interface IBASE {
Void F ();
}
Interface iderived: IBASE {
Void g ();
}
Class C: iderived {
Void IBASE. F (){
// Code for implementing f...
}
Void iderived. G (){
// Code for implementing g...
}
}
Class D: C, iderived {
Public void F (){
// Code for implementing f...
}
Public void g (){
// Code for implementing g...
}
}
Here, the re-implementation of iderived also implements the re-implementation of IBASE, ing IBASE. F to D. F.
4. ing Interface
The class must provide specific implementation for the members of all interfaces listed in the base class table. The implementation of locating interface members in a class is called interface mapping ).
Ing, which indicates a one-to-one correspondence function. The same is true for interface ing. interfaces are implemented through classes. Therefore, each member defined in an interface should correspond to a member of the class to provide specific implementation for it.
The following conditions must be met:
1. If both A and B are member methods, the names, types, and form parameters (including the number of parameters and the type of each parameter) of A and B should be consistent.
2. If both A and B are attributes, the names and types of A and B should be consistent, and the accessors of A and B are similar. However, if A is not an explicit interface member execution body, a can add its own accessors.
3. If a and B are both time-based, the names and types of A and B should be consistent.
4. If both A and B are index indicators, the types and parameters (including the number of parameters and the type of each parameter) of A and B should be consistent. In addition, the accessors of A and B are similar. However, if A is not an explicit interface member execution body, a can add its own accessors.
So how do I determine which class member is implemented for an interface member? Which class is mapped to an interface member? Here, we will describe the interface ing process. Assume that class c implements an interface iinterface, and member is a member of the interface iinterface. The ing process of the interface Member member is as follows:
1. If there is an explicit interface member execution body in C, which corresponds to the interface iinterface and its member, it is used to implement the Member member.
2. If condition (1) is not met and a non-static public member exists in C, the member corresponds to the interface member Member, which is used to implement the Member member.
3. If the above conditions are still not met, search for a base class D of C in the base class list defined in Class C, and replace C with D.
4. Repeat Step 1-3 to traverse all direct and non-direct base classes of C until a member of the class that meets the conditions is found.
5. If not found, an error is reported.
The following is an example of calling a base class method to implement interface members. Class class2 implements the interface interface1. The base class class1 of class class2 also participates in interface ing. That is to say, when class class2 implements the interface interface1, the member method F provided by class class1 is used to implement the member method F of interface interface1:
Interface interface1 {
Void F ();
}
Class class1 {
Public void F (){}
Public void g (){}
}
Class class2: class1, interface1 {
New public void g (){}
}
Note: The interface member includes its own defined members, and includes all the Members defined by the interface's parent interface. During interface ing, you must not only map all explicitly defined members in the interface definition body, but also map all interface members implicitly inherited from the parent interface.
Pay attention to the following two points during interface ing:
1. When determining which member of the class implements the interface member, the explicitly stated interface member in the class is implemented first than other members.
2. members using the private, protected, and static modifiers cannot participate in interface ing. For example:
Interface icloneable {
Object clone ();
}
Class C: icloneable {
Object icloneable. Clone (){...}
Public object clone (){...}
}
In this example, the member icloneable. Clone is called the member clone of the interface icloneable because it is an explicitly stated interface member and has a higher priority than other members.
If a class implements two or more interfaces with the same name, type, and parameter type, one member of the class may implement all these interface members:
Interface iControl {
Void paint ();
}
Interface iform {
Void paint ();
}
Class page: iControl, iform {
Public void paint (){...}
}
Here, the methods of iControl and iform are mapped to the painting method in the class page. Of course, you can also use explicit interface members to implement these two methods:
Interface iControl {
Void paint ();
}
Interface iform {
Void paint ();
}
Class page: iControl, iform {
Public void iControl. Paint (){
// Specific interface implementation code
}
Public void iform. Paint (){
// Specific interface implementation code
}
}
Both of the above statements are correct. However, if the interface member overwrites the parent interface member in inheritance, the implementation of the interface member may have to be mapped to the explicit interface member execution body. See the following example:
Interface IBASE {
Int P {Get ;}
}
Interface iderived: IBASE {
New int P ();
}
The interface iderived inherits from the interface IBASE. In this case, the member methods of the interface iderived overwrite the member methods of the parent interface. Because there are two interface members with the same name, if the implementation of the two interface members does not use the explicit interface member execution body, the compiler will not be able to distinguish interface ing. Therefore, if a class implements the interface iderived, at least one explicit interface member execution body must be defined in the class. The following statements are reasonable:
// 1. Both interface members are implemented using an explicit interface member execution body.
Lass C: iderived {
Int IBASE. p
Get
{// Specific interface implementation code}
Int iderived. P (){
// Specific interface implementation code}
}
// 2. Use an explicit interface member execution body for IBASE interface members.
Class C: iderived {
Int IBASE. p
Get {// specific interface implementation code}
Public int P (){
// Specific interface implementation code}
}
// 3: The iderived interface members are implemented using an explicit interface member execution body.
Class C: iderived {
Public int P
Get {// specific interface implementation code}
Int iderived. P (){
// Specific interface implementation code}
}
In another case, if a class implements multiple interfaces and these interfaces have the same parent interface, this parent interface can be implemented only once.
Using system;
Interface iControl {
Void paint ();
Interface itextbox: iControl {
Void settext (string text );
}
Interface ilistbox: iControl {
Void setitems (string [] items );
}
Class ComboBox: iControl, itextbox, ilistbox {
Void iControl. Paint (){...}
Void itextbox. settext (string text ){...}
Void ilistbox. setitems (string [] items ){...}
}
In the preceding example, the ComboBox class implements three interfaces: iControl, itextbox, and ilistbox. If we think that ComboBox not only implements the iControl interface, but also implements the iControl of its parent interface while implementing itextbox and ilistbox, respectively. In fact, the implementation of the interface itextbox and ilistbox is shared with the implementation of the interface iControl.
We have a comprehensive understanding of the C # interface and basically master how to use the C # interface programming, but in fact, C # is not only used.. NET platform, which also supports the previous COM and can implement COM class. net class conversion, such as C # Calling API.