Interfaces May Be Implement by Classes and Structs. To Indicate That A
Class or struct imports an interface,
The interface identifier is incn The base class list of the class or
Struct. [Example: for example:
Interface iCloneable
{
Object clone ();
}
Interface iComparable
{
Int CompareTo (Object Other);
}
Class Listentry: Icloneable, IComparable
{
PUBLIC OBJECT Clone () {?}
PUBLIC INT COMPARETO (Object Other) {?}
}
End example]
A class or struct thing imports an interface also Implicitly Implements
ALL of the interface? s base interface.
THIS TRUE EVEN IF THE CLASS OR STRUCT DOESN? T Explicitly List All Base
Interfaces in the base class list. [eXample: for
EXAMPLE:
Interface icontrol
{
Void paint ();
}
Interface ITextbox: iControl
{
Void setText (String text);
}
Class Textbox: ITextBox
{
PUBLIC VOID PAINT () {?}
PUBLIC VOID SETTEXT (STRING TEX) {?}
}
Chapter 20 Interfaces
285
Here, Class TextBox Implements Both icontrol and iTextBox. End Examples]
20.4.1 Explicit Interface Member Implementations
For purposes of importing interfaces, a class or struct allow Declare
Explicit Interface Member
Implementations. An expement interface member implemementation is a method,
Property, Event, or Indexer
Declaration That References A Fully Qualified Interface MEMBER NAME.
[EXample: for example
Interface iCloneable
{
Object clone ();
}
Interface iComparable
{
Int CompareTo (Object Other);
}
Class Listentry: Icloneable, IComparable
{
Object iCloneable.clone () {?}
INT iCOMPARE.COMPARETO (Object Other) {?}
}
Here, Icloneable.Clone and ICMPARABLE.COMPARETO ARE EXPLICIT Interface
MEMBER IMPLEMENTATIONS. END
EXAMPLE]
[EXAMPLE: in Some Cases, The Name of An Interface Member May Not Beappriate for the Implementing Class, in IN
Which case the interface member may be implemented Using Explicit Interface
MEMBER IMPLEMENTATION. a class
Implementing a File Abstract, for Example, Would LIKELY IMPLEMENT A
Close Member Function That Has Thae
Effect of release the file resource, and import the dispose mathod of
The idisposable interface using
Explicit Interface Member Implementation:
Interface idisposable {
Void dispose ();
}
Class myfile: idisposable
{
Void idisposable.dispose () {
CLOSE ();
}
Public void close () {
// do what's necessary to close the file
System.gc.suppressFinalize (this);
}
}
End example]
It is not possible to access an expegement interface Member Implementation
THROUGH ITS Fully Qualified Name in A
Method Invocation, Property Access, or Indexer Access. An expedition
Interface Member Implementation Can Only Be
Accessed Through An Interface Instance, and is in That Case Referenced
SIMPLY by Its Member Name.
IT Is a Compile-Time Error for An Explicit Interface Member Implementation
To include Access modifiers, and it is a
Compile-Time Error To include The Modifiers Abstract, Virtual, Override, OR
STATIC.
Explicit Interface Member Implementations Have DiffERENT Accessibility
CHARACTERISTICS THAN Other MEMBERS.
Because Explicit Interface Member Implementations Are Never Accessible
THROUGH THEIR FULLY Qualified Name in A
Method Invocation or a Property Access, They Are I Sense Private.
However, Since They Can Be Accessed THROUGH
An Interface Instance, They Are I Sense Also Public.
Explicit Interface Member Implementations Serve Two Primary Purposes:
Because Explicit Interface Member Implementations Are Not AccessibleRough Class or Struct Instances, THEY
Allow Interface Implementations to Be Excluded from The Public Interface of
a class or struct. this is
C # language specification
286
Particularly Useful When a class or struct imports an internal interface
That is of no no intert to a consumer
Of this class or struct.
• Explicit Interface Member Implementations Allow Disambiguation OF IMPLEMENTATION OF
Interface Members with the Same
Signature. WITHOUT EXPLICIT Interface Member Implementations It Would Be
Impossible for a class or struct to
Have Different Implementations of Interface Members with the Same Signature
And Return Type, AS Would IT BE
Impossible for a class or struct to have, iMplementation At all of
Interface Members with the Same
Signature But with DiffERENT RETURN TYPES.
For an expected to be valid, the class or ib
Struct Must Name An Interface in ITS Base
Class List That Contains a Member Whose Fully Qualified Name, Type, And
Parameter Types Exactly Match THOSE OF
THE EXPLICIT Interface Member Implementation. [Example: thus, in the
FOLLOWING CLASS
Class Shape: iCloneable
{
Object iCloneable.clone () {?}
Int iComparable.Compareto (Object Other) {?} // invalid
}
The Declaration of iComparable.CompareTo Results in a Compile-Time Error
Because iComparable is not
Listed in the base class list of shape and is not a base interface of
Icloneable. Likewise, in the declarations
Class Shape: iCloneable
{
Object iCloneable.clone () {?}
}
Class Ellipse: Shape
{
Object iCloneable.clone () {?} // invalid
}
The Declaration of Icloneable.Clone in Ellipse Results in A Compile-Time
Error Because Icloneable Is Not
Explicitly listed in the base class list of ellipse. End Examples
The full qualified name of an interface member must reason the
Interface in Which the Member Was Declared.
[EXAMPLE: Thus, in the Declarations
Interface icontrol
{
Void paint ();
}
Interface ITextbox: iControl
{
Void setText (String text);
}
Class Textbox: ITextBox
{
Void icontrol.paint () {?}
Void ITEXTBOX.SETTEXT (STRING TEXT) {?}
}
The Explicit Interface Member Implement OF Paint Must Be Written As
Icontrol.paint. End Example]
20.4.2 Interface Mapping
A class or struct Must Provide Implementations of All MEMBERS OF THE
Interfaces That Are listed in the base class
List of the class or struct. The process of locating us
Interface MEMBERS in An Implementing Class. INTERFACE CLASS
Or struct is known as interface mapping.
Interface mapping for a class or struct c locates an importation for
Each MEMBER OF Each Interface Specified in
The base class list of c. The importation of a particular interface
Member I.m, Where I is the interface in
Which the member m is declared, is determined by Examing Each Class OR
Struct S, Starting with c and reporting
For Each Successive Base Class of C, UnTil A Match Is Located:
Chapter 20 Interfaces
287
? If s contains a declaration of an expected interface member
Implementation That Matches I and M, THIS
MEMBER IS The Implementation of i.m.
OtherWise, IF S Contains a Declaration of a non-static public member That
Matches M, THIS MEMBER IS THE
Implementation of i.m.
A Compile-Time Error Occurs IF IMPLEMENTATIONS Cannot Be Located for All
MEMBERS OF All Interfaces Specified in
The base class list of c. the members of an interface incrude Those Members
That area inherited from baseinterface.
For purposes of interface mapping, a class member a matches an interface
MEMBER B WHEN:
? A and B Are Methods, And the Name, Type, and Formal Parameter Lists of A
And B Are Identical.
A and B Are Properties, The Name and Type of a and b Are Identical, And A
HAS The Same Accessors as B (a is
Permitted to Have Additional Accessors if it is not an expected interface
MEMBER IMPLEMENTATION.
A and B Are Events, And The Name and Type of A and B Are Identical.
? A and B Are Indexers, The Type and Formal Parameter Lists of A and B Are
Identical, And a Has the Same
Accessors as B (a is permitted to have not an an informationAL accessors if it is not an
Explicit Interface Member
Implementation.
NOTABLE IMPLICATIONS OF THE INTERFACE-MAPPING ALGORITHM Are:
• Explicit Interface Member Implementations Take Precedence over Other
MEMBERS in the Same Class or Struct
When Determining The Class or Struct Member That Implements An Interface
MEMBER.
Neither Non-Public Nor Static Members Participate In Interface Mapping.
[EXAMPLE: in The Example
Interface iCloneable
{
Object clone ();
}
Class C: Icloneable
{
Object iCloneable.clone () {?}
PUBLIC OBJECT Clone () {?}
}
The Icloneable.clone Member of C Becomes The Implementation of Clone in IN CLONE IN
Icloneable Because Explicit
Interface Member Implementations Take Precedence over Other Members. End
EXAMPLE]
IF a class or struct implementations Two or more interfaces containing a member
With the Same Name, Type, And
Parameter Types, It is Possible To map Each of Those Interface Members ONTO
A Single Class or Struct Member.
[EXample: for example
Interface icontrol
{
Void paint ();
}
Interface IFORM
{
Void paint ();
}
Class Page: icontrol, iForm {
PUBLIC VOID PAINT () {?}
}
Here, The Paint Methods of Both Icontrol and iForm Are Mapped ONTO THE
Paint Method in Page. IT IS OF
Course Also Possible to Have Separate Explicit Interface Member
Implementations for the two methods. end
EXAMPLE]
C # language specification
288
IF a class or struct imports an interface truins Hidden Members,
Then Some Members Must Necessarily
BE IMPLEMENTED THROUGH Explicit Interface Member Implementations.
For example
Interface ibase
{
INT P {Get;}
}
Interface Iderived: IBASE
{
New int p ();
}
An Implementation of this Interface Would Require At Least One Explicit
Interface Member Implementation, And
Would Take ONE FOLLOWING FORMS
Class C: IDerived
{
INT IBASE.P {GET {?}}
Iden applived.p () {?}
}
Class C: IDerived
{
Public int p {get {?}}
Iden applived.p () {?}
}
Class C: IDerived
{
INT IBASE.P {GET {?}}
Public int P () {?}
}
End example]
WHEN a class imports multiple interfaces That Have The Same Base
Interface, There Can Be Only One
Implementation of the base interface. [EXAMPLE: in The Example
Interface icontrol
{
Void paint ();
}
Interface ITextbox: iControl
{
Void setText (String text);
}
Interface IListbox: icontrol
{
Void setItems;
}
Class ComboBox: Icontrol, ITextBox, IListbox
{
Void icontrol.paint () {?}
Void ITEXTBOX.SETTEXT (STRING TEXT) {?}
Void IListBox.SetItems (String [] items) {?}
}
IT is not Possible to Have Separate Implementations for the icontrol named
In The Base Class List, The icontrol
Inherited by ITextBox, and the icontrol inherited by ilistbox. indeed,
There is no notion of a separate
Identity For There Interfaces. Rather, The Implementations of ITextBox AndilistBox Share The Same
Implementation of iControl, And ComboBox Is Simply Considered to Implement
Three Interfaces, Icontrol,
ITextBox, and ilistbox. End Example]
The Members of a base class participate in interface mapping. [Example: in
The Example
Chapter 20 Interfaces
289
Interface interface1
{
Void f ();
}
Class class1
{
Public void f () {}
Public void g () {}
}
Class Class2: Class1, Interface1
{
NEW PUBLIC VOID G () {}
}
The Method F IN Class1 IS Used In Class2's Implementation of Interface1.
End example]
20.4.3 Interface Implementation Inheritance
A class inherits all interface us..
WITHOUT EXPLICITLY RE-Implementing An Interface, A Derived Class Cannot in
Any Way ALTER The Interface Mappings IT
Inherits from its base classes. [EXAMPLE: for Example, In the Declarations
Interface icontrol
{
Void paint ();
}
Class Control: iControl
{
PUBLIC VOID PAINT () {?}
}
Class Textbox: Control
{
NEW PUBLIC VOID PAINT () {?}
}
The Paint Method in TextBox Hides The Paint Method in Control, But It Does
NOT ALTER THE MAPPING OF
Control.Paint Onto Icontrol.Paint, and Calls to Paint Through CLASS
Instances and interface instances, INSTANCES
Will Have the Following Effects
Control C = New Control ();
TextBox T = New TextBox ();
IControl IC = C;
Icontrol it = t;
C.Paint (); // invokes control.paint ();
T.Paint (); // invokes textbox.paint ();
Ic.paint (); // invokes control.paint ();
IT.Paint (); // invokes control.paint ();
End example]
However, When An Interface Method Is Mapped ONTO A Virtual Method in A
Class, IT IS Possible for Derived Classes
To override The Virtual Method and alter the us. [example: for example, restriting the
Declarations Above To
Interface icontrol
{
Void paint ();
}
Class Control: iControl
{
PUBLIC VIRTUAL VOID PAINT () {?}
}
C # language specification
290
Class Textbox: Control
{
Public Override Void Paint () {?}
}
The Following Effects Will Now Be Observed
Control C = New Control ();
TextBox T = New TextBox ();
IControl IC = C;
Icontrol it = t;
C.Paint (); // invokes control.paint ();
T.Paint (); // invokes textbox.paint ();
Ic.paint (); // invokes control.paint ();
IT.Paint (); // invokes textbox.paint ();
End example]
Since Explicit Interface Member Implementations Cannot Be Declared Virtual,
IT is not possible to override an
Explicit Interface Member Implementation. However, IT IS Perfectly Valid
For An expedition interface member
Implementation to Call Another Method, And That Other Method Can Be
Declared Virtual To Allow Derived Classes To
Override it. [example: 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, Classes Derived from Control CAN Specialize The Implementation of
Icontrol.paint by overriding the
PaintControl method. End Example]
20.4.4 Interface RE-Implementation
A class what inherits an interface importation is permitted to
RE-Implement the interface by incruding it in the
Base Class List.
A re-usteation of an interface Follows Exactly the Same Interface
Mapping Rules as an initial
Implementation of an interface. thus, the inherited interface mapping hasno effect whatsoever on the interface
Mapping Established for the Re-Implementation of The Interface. [Example:
For example, in the declarations
Interface icontrol
{
Void paint ();
}
Class Control: iControl
{
Void icontrol.paint () {?}
}
Class MyControl: Control, iControl
{
Public void paint () {}
}
The Fact That Control Maps icontrol.Paint Onto Control.icontrol.paint
Doesn? T Affect The Reimplementation
In MyControl, Which Maps Icontrol.Paint Onto myControl.paint. End Examples]
Chapter 20 Interfaces
291
Inherited Public Member Declarations and inherited Explicit Interface
Member Declarations Participate in The
Interface Mapping Process for Re-Implement Interfaces. [EXAMPLE: for
EXAMPLE
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 Imethods in Derived Maps The Interface Methods
Onto deerived.f,
Base.imethods.g, derived.imethods.h, and base.i. End Example]
WHEN a class imports an interface, IT Implicitly Also Implements All of
That Interface? s base interface.
LIKEWISE, A RE-IMPLEMENTATION OF ANTERFACE IS Also Implicitly A
RE-IMPLEMENTATION OF All of The Interface? S Base
Interfaces. [example: for example
Interface ibase
{
Void f ();
}
Interface Iderived: IBASE
{
Void g ();
}
Class C: IDerived
{
Void ibase.f () {?}
Void iderived.g () {?}
}
Class D: C, Iderived
{
PUBLIC VOID F () {?}
PUBLIC VOID G () {?}
}
Here, The Re-Implementation of Iderived Also Re-Implements Ibase, Mappingibase.f ONTO D.F. End
EXAMPLE]
20.4.5 Abstract Classes and Interfaces
Like a Non-Abstract Class, An Abstract Class Must Provide Implementations
Of all members of the interfaces That Are
Listed in the base class list of the class. However, An Abstract Class IS
Permitted to Map Interface Methods ONTO
Abstract Methods. [Example: for Example
Interface iMethods
{
Void f ();
Void g ();
}
C # language specification
292
Abstract Class C: iMethods
{
Public abstract void f ();
Public Abstract Void g ();
}
Here, The Implementation of Imethods Maps F and G ONTO Abstract Methods,
Which Must Be Overridden in NonabStract
Classes this derive from c. End Example]
Explicit Interface Member Implementations Cannot Be Abstract, But Explicit
Interface Member Implementations Are
Of Course Permitted to Call Abstract Methods. [EXAMPLE: for Example
Interface iMethods
{
Void f ();
Void g ();
}
Abstract Class C: iMethods
{
Void iMethods.f () {ff ();
Void iMethods.g () {gg ();
Protected abstract void ff ();
Protected abstract void gg ();
}
Here, Non-Abstract Classes That Derive from c Would Be Required To override
Ff and gg, thus providing the activity
Implementation of iMethods. End Example]