20.2 Interface Members

xiaoxiao2021-04-05  287

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]

转载请注明原文地址:https://www.9cbs.com/read-132005.html

New Post(0)