The Members of An Interface Are The Members inherited from the Base
Interfaces and the members declared by the
Interface itself.
Interface-Member-Declarations:
Interface-Member-Declaration
Interface-Member-Declarations Interface-Member-Declaration
Interface-Member-Declaration:
Interface-method-declaration
Interface-Property-Declaration
Interface-Event-Declaration
Interface-Indexer-Declaration
An Interface Declaration May Declare Zero or More Members. The Members of
An Interface Must Be Methods,
Properties, Events, or Indexers. An Interface Cannot Contain Conntants,
Fields, Operators, Instance Construction,
Destructors, or Types, Nor Can An Interface Contain Static Members of Any
Kind.
All Interface Member Implicitly Have Public Access. It is a compile-time
Error for Interface Member Declarations
To include any modifiers. in particular, interface members cannot be
Declared with the modifiers abstract,
Public, Protected, Internal, Private, Virtual, Override, or Static.
[EXAMPLE: THE EXAMPLE
Public Delegate Void StringListevent (istringlist sender);
Public interface istringlist
{
Void Add (String S);
INT count {get;}
Event stringlistevent change;
Chapter 20 Interfaces
281
String this [int index] {get; set;}
}
Declares An Interface That Contains One Each of The Possible Kinds of
MEMBERS: a Method, a property, an es,
And an indexer. End Example]
An Interface-Declaration Creates A New Declaration Space (10.3), and the
Interface-Member-Declarations
Immediately contained by the interface-declaration Introduce New Members
INTO this Declaration Space. The
FOLLOWING Rules Apply to Interface-Member-Declarations:
? The name of a method must differ from the names of all proties and
Events declared in the Same Interface.in Addition, The Signature (10.6) of a method must diffrity
Signatures of all other Methods Declared in
The Same Interface, And Two Methods Decland In The Same Interface May Not
Have Signatures That Difer Solely
By Ref and out.
? The name of a property or event must differ from the names of all other
MEMBERS DECLARED in The Same
Interface.
? Signature of an indexer Must Differ from the signatures of all od
Indexers Decland in the Same
Interface.
The inherited members of an interface area specification not part of the
Declaration Space of the interface. thus, an
Interface is allowed to declare a member with the Same Name OR SIGNATURE AS
An inherited member. When this THIS
Occurs, the derived interface member is said to hide the base interface
MEMBER. HIDING An Inherited Member IS
NOT CONSIED An Error, But it does cause the compiler to ssue a warning.
To support the Warning, The Warning, The Warning, The Warning, The Warning, The WARNING
Declaration of the derived interface member Must Include a new modifier to
Indicate That the deived member is
Intended to hide the base member. this Topic is discussed further in §10.7.1
.2.
IF a new modifier is include in a declaration trat? T hide an
Inherited Member, A Warning Is Issued To That
Effect. This Warning is support by removing the new modifier.
[NOTE: The Members in Class Object Are Not, Strictly Speaking, Members of
Any Interface (20.2). However, The
MEMBERS IN Class Object Are Available Via Member Lookup in Any Interface
TYPE (14.3). End Note]
20.2.1 Interface Methods
Interface Methods Are Declared Using Interface-Method-Declarations:
Interface-method-declaration:
AttributeSopt newopt return-type identifier (formal-parameter-listopt); the attributes, return-type, identifier, and final-parameter-list of an
Interface method Declaration Have the Same
Meaning as those of a method Declaration in a class (§17.5). An interface
Method Declaration is not permitted to
Specify A Method Body, and the declaration therefore always ends with a
Semicolon.
20.2.2 Interface Properties
Interface Properties Are Declared Using Interface-Property-Declarations:
Interface-Property-Declaration:
AttributeSopt Newopt Type Identifier {Interface-Accessors}
Interface-Accessors:
AttributeSopt get;
AttributeSopt set;
AttributeSopt get; attributeesopt set;
AttributeSopt set; attributesopt get;
THE Attributes, Type, and Identifier of An Interface Property Declaration
Have The Same Meaning As Those of A
Property Declaration In A Class (§17.6).
The Accessors of An Interface Property Declaration Correspond to The
Accessors of a class printy Declaration
(§17.6.2), Except That The Accessor Body Must Always Be a Semicolon. Thus,
The Accessors Simply Indicate WHether
The property is read-write, read-only, or write-only.
C # language specification
282
20.2.3 Interface Events
Interface Events Are Declared Using Interface-Event-Declarations:
Interface-Event-Declaration:
AttributeSopt Newopt Event Type Identifier;
THE Attributes, Type, And Identifier of An Interface Event Declaration Have
The Same Meaning As Those of An Event
Declaration in a class (§17.7).
20.2.4 Interface Indexers
Interface Indexers Are Declared Using Interface-Indexer-Declarations:
Interface-Indexer-Declaration:
AttributeSopt Newopt Type this [Formal-parameter-list] {
Interface-accessors}
The attributes, type, and formal-parameter-list of an interface indexerdeclarative have the Same meaning as
Those of An Indexer Declaration In a class (§17.8).
The Accessors of An Interface Indexer Declaration Correspond To The
Accessors of a class indexer declaration
(§17.8), Except That The Accessor Body Must Always Be a SEMICOLON. Thus,
The Accessors Simply Indicate WHether
The indexer is read-write, read-only, or write-only.
20.2.5 Interface MEMBER Access
Interface Member Access (14.5.4) and Indexer
Access (14.5.6.2) Expressions of
The form i.m and i [a], WHERE I is an expression haVing an interface type, m
Is A Method, Property, or Event of
That Interface Type, And A is an indexer argument list.
For Interfaces That Are Strictly Single-Inheritance (Each Interface in The
Inheritance Chain Has Exactly Zero or One
Direct Base Interface, The Effects of The Member Lookup (14.3), Method
Invocation (14.5.5.1), and indexer
Access (§14.5.6.2) Rules Are EXACTLY THE Same as for classes and structs:
More derived members hide less derived
MEMBERS with The Same Name or Signature. However, for multiple-inheritance
Interfaces, Ambiguities Can Occur
When Two or More Unrelated Base Interfaces Declare Members with The Same
Name Or Signature. this Section
Shows Several Examples of Such Situations. in All Cases, Explicit Casts CAN
Be buy to resolve the ambiguities.
[EXAMPLE: in The Example
Interface ilist
{
INT count {get; set;}
}
Interface ICOUNTER
{
Void Count (INT I);
}
Interface ilistcounter: IList, ICOUNTER {}
Class C
{
Void test (ilistcounter x) {
x.count (1); // error
x.count = 1; // error
(IList) x) .count = 1; // ok, invokes ilist.count.set
(ICounter) .count (1); // ok, invokes iCounter.count}
}
The First Two Statements Cause Compile-Time Errors Because The Member
Lookup (14.3) of Count in
IListCounter is ambiguous. As illustrate by the example, The Ambiguity IS
Resolved by casting x to the
Appropriate Base Interface Type. Such Casts Have No Run-Time COSTS? THEY
Merely consist of viewing the instance
As a less derived type at compile-time. End Example]
[EXAMPLE: in The Example
Chapter 20 Interfaces
283
Interface Iinteger
{
Void Add (INT I);
}
Interface idouble
{
Void Add (Double D);
}
Interface Inumber: Iinteger, iDouble {}
Class C
{
Void test (inumber n) {
n.add (1); // Error, Both Add Methods Are Applicable
n.add (1.0); // OK, ONLY iDOUBLE.ADD IS Applicable
(Integer) .add (1); // ok, only integer.add is a candidate
(IDouble) n) .add (1); // ok, only idouble.add is a Candidate
}
}
The Invocation N.Add (1) IS Ambiguous Because A Method Invocation (14.5.5.1)
Requires all overloaded
Candidate Methods to Be Declared In the Same Type. However, The Invocation
n.add (1.0) is permitted Because
ONLY iDOUBLE.Add Is Applicable. When Explicit Casts Are INSERTED, THERE IS
Only One Candidate Method, And Thus
No Ambiguity. End Example]
[EXAMPLE: in The Example
Interface ibase
{
Void F (INT I);
}
Interface Ileft: IBASE
{
New Void F (INT I);
}
Interface Iright: IBASE
{
Void g ();
}
Interface IDerived: Ileft, Iright {}
Class A
{
Void test (iderived d) {
D.f (1); // Invokes Ileft.f
((Ibase) d) .f (1); // invokes ibase.f
((Ileft) d) .f (1); // Invokes Ileft.f
((IRIGHT) D) .f (1); // invokes ibase.f
}
}
The ibase.f member is hidden by The Ileft.f Member. The Invocation D.f (1)
Thus Selects Ileft.f, Even
.
THE INTUTIVE RULE for HIDING IN MULTIPLE-INHERITANCE INTERFECES IS SIMPLY
THIS: IF a Member Is Hidden in Any Access
Path, IT IS Hidden in All Access Paths. Because The Access Path from
Iderived to Ileft to ibase HIDES
Ibase.f, The Member IS Also Hidden in The Access Path from Iderived To
Iright to ibase. End Example]