java implement 泛型_csharplang.zh-cn

ms.openlocfilehash

ms.sourcegitcommit

ms.translationtype

ms.contentlocale

ms.lasthandoff

ms.locfileid

0a09585f4f885647230354c66a2449abb7ef1f44

94a3d151c438d34ede1d99de9eb4ebdc07ba4699

MT

zh-CN

04/25/2019

64488779

接口Interfaces

接口定义一个协定。An interface defines a contract. 类或结构实现的接口必须遵守其协定。A class or struct that implements an interface must adhere to its contract. 一个接口可能从多个基接口继承,类或结构可以实现多个接口。An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

接口可以包含方法、 属性、 事件和索引器。Interfaces can contain methods, properties, events, and indexers. 接口本身不提供实现,它定义的成员。The interface itself does not provide implementations for the members that it defines. 接口只是指定必须由实现接口的类或结构提供的成员。The interface merely specifies the members that must be supplied by classes or structs that implement the interface.

接口声明Interface declarations

Interface_declaration是type_declaration (类型声明),其用于声明新的接口类型。An interface_declaration is a type_declaration (Type declarations) that declares a new interface type.

interface_declaration

: attributes? interface_modifier* 'partial'? 'interface'

identifier variant_type_parameter_list? interface_base?

type_parameter_constraints_clause* interface_body ';'?

;

Interface_declaration包含一组可选特性(特性) 后, 跟一组可选的interface_modifiers (接口修饰符) 后, 跟一个可选partial修饰符,关键字后跟interface和一个标识符命名接口,跟一个可选variant_type_parameter_list规范 (变体类型的参数列表) 后, 跟一个可选interface_base规范 (的基接口) 后, 跟一个可选type_parameter_constraints_clauses 规范 (类型参数约束)后, 跟interface_body (接口正文) 后, 跟分号 (可选)。An interface_declaration consists of an optional set of attributes (Attributes), followed by an optional set of interface_modifiers (Interface modifiers), followed by an optional partial modifier, followed by the keyword interface and an identifier that names the interface, followed by an optional variant_type_parameter_list specification (Variant type parameter lists), followed by an optional interface_base specification (Base interfaces), followed by an optional type_parameter_constraints_clauses specification (Type parameter constraints), followed by an interface_body (Interface body), optionally followed by a semicolon.

接口修饰符Interface modifiers

Interface_declaration可以根据需要包含一系列接口修饰符:An interface_declaration may optionally include a sequence of interface modifiers:

interface_modifier

: 'new'

| 'public'

| 'protected'

| 'internal'

| 'private'

| interface_modifier_unsafe

;

它是同一修饰符在接口声明中出现多次的编译时错误。It is a compile-time error for the same modifier to appear multiple times in an interface declaration.

new修饰符仅允许在类中定义的接口上。The new modifier is only permitted on interfaces defined within a class. 它指定该接口通过相同的名称,隐藏继承的成员中所述的新修饰符。It specifies that the interface hides an inherited member by the same name, as described in The new modifier.

public, protected, internal,和private修饰符控制接口的可访问性。The public, protected, internal, and private modifiers control the accessibility of the interface. 具体取决于接口声明发生的上下文,可能会允许仅在部分这些修饰符 (声明可访问性)。Depending on the context in which the interface declaration occurs, only some of these modifiers may be permitted (Declared accessibility).

Partial 修饰符Partial modifier

partial修饰符指示这interface_declaration是分部类型声明。The partial modifier indicates that this interface_declaration is a partial type declaration. 具有相同名称的封闭命名空间或类型声明中的多个分部接口声明组合到窗体一个接口声明,遵循的规则中指定分部类型。Multiple partial interface declarations with the same name within an enclosing namespace or type declaration combine to form one interface declaration, following the rules specified in Partial types.

变体类型参数列表Variant type parameter lists

变体类型参数列表只能出现在接口和委托类型。Variant type parameter lists can only occur on interface and delegate types. 与普通的差别type_parameter_list是可选的 s variance_annotation上每个类型参数。The difference from ordinary type_parameter_lists is the optional variance_annotation on each type parameter.

variant_type_parameter_list

: ''

;

variant_type_parameters

: attributes? variance_annotation? type_parameter

| variant_type_parameters ',' attributes? variance_annotation? type_parameter

;

variance_annotation

: 'in'

| 'out'

;

如果方差批注out,类型参数称为协变。If the variance annotation is out, the type parameter is said to be covariant. 如果方差批注in,类型参数称为逆变。If the variance annotation is in, the type parameter is said to be contravariant. 如果没有任何变化批注,类型参数称固定。If there is no variance annotation, the type parameter is said to be invariant.

在示例In the example

interface C

{

X M(Y y);

Z P { get; set; }

}

X 为协变Y是逆变和Z是固定不变。X is covariant, Y is contravariant and Z is invariant.

变体安全Variance safety

方差批注类型形参列表中的一种类型的匹配项将限制类型的类型声明中可能发生的位置的位置。The occurrence of variance annotations in the type parameter list of a type restricts the places where types can occur within the type declaration.

一种类型T是输出不安全如果下列之一保存:A type T is output-unsafe if one of the following holds:

T 是逆变类型参数T is a contravariant type parameter

T 为具有输出不安全的元素类型的数组类型T is an array type with an output-unsafe element type

T 是一个接口或委托类型S从泛型类型构造S至少一个 whereAi以下之一保存:T is an interface or delegate type S constructed from a generic type S where for at least one Ai one of the following holds:

Xi 协变或固定和Ai是不安全的输出。Xi is covariant or invariant and Ai is output-unsafe.

Xi 是逆变或固定条件和Ai是输入安全的。Xi is contravariant or invariant and Ai is input-safe.

一种类型T是输入不安全如果下列之一保存:A type T is input-unsafe if one of the following holds:

T 是协变类型参数T is a covariant type parameter

T 是输入不安全的元素类型的数组类型T is an array type with an input-unsafe element type

T 是一个接口或委托类型S从泛型类型构造S至少一个 whereAi以下之一保存:T is an interface or delegate type S constructed from a generic type S where for at least one Ai one of the following holds:

Xi 协变或固定和Ai是不安全的输入。Xi is covariant or invariant and Ai is input-unsafe.

Xi 是逆变或固定条件和Ai是不安全的输出。Xi is contravariant or invariant and Ai is output-unsafe.

直观地说,输出不安全类型禁止的中的输出位置,并在输入位置禁止的输入不安全类型。Intuitively, an output-unsafe type is prohibited in an output position, and an input-unsafe type is prohibited in an input position.

一种类型是输出安全如果不是输出不安全,并输入安全如果不输入不安全。A type is output-safe if it is not output-unsafe, and input-safe if it is not input-unsafe.

变化转换Variance conversion

方差批注的目的是提供更宽松 (但仍类型安全的) 转换成接口和委托类型。The purpose of variance annotations is to provide for more lenient (but still type safe) conversions to interface and delegate types. 到此结束的隐式定义 (隐式转换) 和显式转换 (显式转换) 进行可转换,按如下所示定义这一概念的使用:To this end the definitions of implicit (Implicit conversions) and explicit conversions (Explicit conversions) make use of the notion of variance-convertibility, which is defined as follows:

一种类型T可变化转换为某种T如果T接口或委托类型使用变体类型参数声明T,并为每个变体类型参数Xi以下项之一包含:A type T is variance-convertible to a type T if T is either an interface or a delegate type declared with the variant type parameters T, and for each variant type parameter Xi one of the following holds:

Xi 是协变和隐式引用或标识转换存在从Ai到 BiXi is covariant and an implicit reference or identity conversion exists from Ai to Bi

Xi 是逆变和隐式引用或标识转换存在从Bi到 AiXi is contravariant and an implicit reference or identity conversion exists from Bi to Ai

Xi 是固定条件和标识转换存在从Ai到 BiXi is invariant and an identity conversion exists from Ai to Bi

基接口Base interfaces

接口可以继承自零个或多个接口类型,称为显式基接口的接口。An interface can inherit from zero or more interface types, which are called the explicit base interfaces of the interface. 时接口具有一个或多个显式基接口,然后在该接口的声明中的接口标识符后跟冒号和逗号分隔的基接口类型的列表。When an interface has one or more explicit base interfaces, then in the declaration of that interface, the interface identifier is followed by a colon and a comma separated list of base interface types.

interface_base

: ':' interface_type_list

;

对于构造的接口类型,显式基接口构成方法为泛型类型声明中,对其执行显式基接口声明替换为每个type_parameter中的基接口相应的声明type_argument构造类型。For a constructed interface type, the explicit base interfaces are formed by taking the explicit base interface declarations on the generic type declaration, and substituting, for each type_parameter in the base interface declaration, the corresponding type_argument of the constructed type.

接口的显式基接口必须至少与接口本身相同的可访问性 (可访问性约束)。The explicit base interfaces of an interface must be at least as accessible as the interface itself (Accessibility constraints). 例如,它是指定的编译时错误private或internal接口中interface_base的public接口。For example, it is a compile-time error to specify a private or internal interface in the interface_base of a public interface.

它是一个接口以直接或间接从自身继承的编译时错误。It is a compile-time error for an interface to directly or indirectly inherit from itself.

的基接口已显式基接口并其基接口的接口。The base interfaces of an interface are the explicit base interfaces and their base interfaces. 换而言之,组的基接口是完全的显式基接口,其显式基接口,诸如此类的可传递闭包。In other words, the set of base interfaces is the complete transitive closure of the explicit base interfaces, their explicit base interfaces, and so on. 接口继承其基接口的所有成员。An interface inherits all members of its base interfaces. 在示例In the example

interface IControl

{

void Paint();

}

interface ITextBox: IControl

{

void SetText(string text);

}

interface IListBox: IControl

{

void SetItems(string[] items);

}

interface IComboBox: ITextBox, IListBox {}

接口的基IComboBox都IControl, ITextBox,和IListBox。the base interfaces of IComboBox are IControl, ITextBox, and IListBox.

换而言之,IComboBox上述接口继承的成员SetText并SetItems以及Paint。In other words, the IComboBox interface above inherits members SetText and SetItems as well as Paint.

每个基接口的接口必须是安全的输出 (变体安全)。Every base interface of an interface must be output-safe (Variance safety). 类或结构还将隐式实现接口实现的所有接口的基接口。A class or struct that implements an interface also implicitly implements all of the interface's base interfaces.

接口体内Interface body

Interface_body接口的定义接口的成员。The interface_body of an interface defines the members of the interface.

interface_body

: '{' interface_member_declaration* '}'

;

接口成员Interface members

接口的成员是继承自基接口的成员和成员声明由接口本身。The members of an interface are the members inherited from the base interfaces and the members declared by the interface itself.

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 constants, fields, operators, instance constructors, destructors, or types, nor can an interface contain static members of any kind.

所有接口成员隐式都具有公共访问权限。All interface members implicitly have public access. 它是接口成员声明中包含任何修饰符的编译时错误。It is a compile-time error for interface member declarations to include any modifiers. 具体而言,不能具有修饰符声明接口成员abstract, public, protected, internal, private, virtual, override,或static。In particular, interfaces members cannot be declared with the modifiers abstract, public, protected, internal, private, virtual, override, or static.

该示例The example

public delegate void StringListEvent(IStringList sender);

public interface IStringList

{

void Add(string s);

int Count { get; }

event StringListEvent Changed;

string this[int index] { get; set; }

}

声明包含之一的每个可能类型的成员的接口:一种方法、 属性、 事件和索引器。declares an interface that contains one each of the possible kinds of members: A method, a property, an event, and an indexer.

Interface_declaration创建一个新的声明空间 (声明),并且interface_member_declarations 立即包含interface_declaration引入此声明空间的新成员。An interface_declaration creates a new declaration space (Declarations), and the interface_member_declarations immediately contained by the interface_declaration introduce new members into this declaration space. 以下规则适用于interface_member_declarations:The following rules apply to interface_member_declarations:

方法的名称必须不同于所有属性和相同的接口中声明的事件的名称。The name of a method must differ from the names of all properties and events declared in the same interface. 此外,签名 (签名和超载) 的一种方法必须不同于同一接口中声明的所有其他方法的签名和签名不能在同一个接口中声明的两种方法,完全由不同ref和out。In addition, the signature (Signatures and overloading) of a method must differ from the signatures of all other methods declared in the same interface, and two methods declared in the same interface may not have signatures that differ 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.

索引器的签名必须不同于同一接口中声明的所有其他索引器的签名。The signature of an indexer must differ from the signatures of all other indexers declared in the same interface.

接口的继承的成员是专门不属于该接口声明空间。The inherited members of an interface are specifically 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 occurs, the derived interface member is said to hide the base interface member. 隐藏继承的成员不被视为错误,但它确实会导致编译器发出警告。Hiding an inherited member is not considered an error, but it does cause the compiler to issue a warning. 若要禁止显示警告,请在派生的接口成员的声明必须包括new修饰符以指示派生的成员用于隐藏基类成员。To suppress the warning, the declaration of the derived interface member must include a new modifier to indicate that the derived member is intended to hide the base member. 本主题讨论中进一步通过继承隐藏。This topic is discussed further in Hiding through inheritance.

如果new修饰符包含在不隐藏继承的成员的声明,该结果发出警告。If a new modifier is included in a declaration that doesn't hide an inherited member, a warning is issued to that effect. 通过删除禁止显示此警告new修饰符。This warning is suppressed by removing the new modifier.

请注意,在类成员object不严格地讲,任何接口的成员 (接口成员)。Note that the members in class object are not, strictly speaking, members of any interface (Interface members). 但是,在类成员object可通过成员查找中任何接口类型 (成员查找)。However, the members in class object are available via member lookup in any interface type (Member lookup).

接口方法Interface methods

使用声明接口方法interface_method_declarations:Interface methods are declared using interface_method_declarations:

interface_method_declaration

: attributes? 'new'? return_type identifier type_parameter_list

'(' formal_parameter_list? ')' type_parameter_constraints_clause* ';'

;

特性, return_type,标识符,以及formal_parameter_list的接口方法声明具有相同这意味着与方法声明在类中的 (方法)。The attributes, return_type, identifier, and formal_parameter_list of an interface method declaration have the same meaning as those of a method declaration in a class (Methods). 接口方法声明不允许指定方法体中,并声明因此始终以分号结尾。An interface method declaration is not permitted to specify a method body, and the declaration therefore always ends with a semicolon.

每种形式参数类型的接口方法必须是输入安全 (变体安全),并返回类型必须为void或输出安全。Each formal parameter type of an interface method must be input-safe (Variance safety), and the return type must be either void or output-safe. 此外,每个类类型约束、 接口类型约束和类型参数约束上方法的任何类型参数必须是输入安全的。Furthermore, each class type constraint, interface type constraint and type parameter constraint on any type parameter of the method must be input-safe.

这些规则可确保任何协变或逆变的接口的使用情况保持类型安全。These rules ensure that any covariant or contravariant usage of the interface remains type-safe. 例如,应用于对象的For example,

interface I { void M() where U : T; }

是非法的因为的使用情况T用作类型参数约束上U不是输入安全的。is illegal because the usage of T as a type parameter constraint on U is not input-safe.

已不存在此限制可能会违反类型安全方式如下:Were this restriction not in place it would be possible to violate type safety in the following manner:

class B {}

class D : B{}

class E : B {}

class C : I { public void M() {...} }

...

I b = new C();

b.M();

这是实际调用C.M。This is actually a call to C.M. 但该调用需要E派生自D,因此此处违反类型安全。But that call requires that E derive from D, so type safety would be violated here.

接口属性Interface properties

接口属性的声明使用interface_property_declarations:Interface properties are declared using interface_property_declarations:

interface_property_declaration

: attributes? 'new'? type identifier '{' interface_accessors '}'

;

interface_accessors

: attributes? 'get' ';'

| attributes? 'set' ';'

| attributes? 'get' ';' attributes? 'set' ';'

| attributes? 'set' ';' attributes? 'get' ';'

;

特性,类型,并标识符接口属性声明的类中具有相同含义的属性声明 (属性)。The attributes, type, and identifier of an interface property declaration have the same meaning as those of a property declaration in a class (Properties).

接口属性声明的访问器对应于类属性声明的访问器 (访问器),只不过访问器正文必须始终是一个分号。The accessors of an interface property declaration correspond to the accessors of a class property declaration (Accessors), 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.

接口属性的类型必须是输出安全是否存在 get 访问器,并且必须是输入安全如果没有 set 访问器。The type of an interface property must be output-safe if there is a get accessor, and must be input-safe if there is a set accessor.

接口事件Interface events

使用声明接口事件interface_event_declarations:Interface events are declared using interface_event_declarations:

interface_event_declaration

: attributes? 'new'? '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 (Events).

接口事件的类型必须是输入安全。The type of an interface event must be input-safe.

接口索引器Interface indexers

使用声明接口索引器interface_indexer_declarations:Interface indexers are declared using interface_indexer_declarations:

interface_indexer_declaration

: attributes? 'new'? type 'this' '[' formal_parameter_list ']' '{' interface_accessors '}'

;

特性,类型,并formal_parameter_list接口索引器声明的类 (中具有与索引器声明相同的含义索引器)。The attributes, type, and formal_parameter_list of an interface indexer declaration have the same meaning as those of an indexer declaration in a class (Indexers).

接口索引器声明的访问器对应于类索引器声明的访问器 (索引器),只不过访问器正文必须始终是一个分号。The accessors of an interface indexer declaration correspond to the accessors of a class indexer declaration (Indexers), 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.

接口索引器的所有形式参数类型必须是输入安全。All the formal parameter types of an interface indexer must be input-safe . 此外,任何out或ref形参类型还必须是安全的输出。In addition, any out or ref formal parameter types must also be output-safe. 请注意,甚至out参数需是输入安全的由于基础执行平台的限制。Note that even out parameters are required to be input-safe, due to a limitation of the underlying execution platform.

接口索引器的类型必须是输出安全是否存在 get 访问器,并且必须是输入安全如果没有 set 访问器。The type of an interface indexer must be output-safe if there is a get accessor, and must be input-safe if there is a set accessor.

接口成员访问Interface member access

成员访问通过访问接口成员 (成员访问) 和索引器访问 (索引器访问) 形式的表达式I.M并I[A],其中I是一个接口类型,M是方法、 属性或事件的接口类型,和A是索引器参数列表。Interface members are accessed through member access (Member access) and indexer access (Indexer access) expressions of the form I.M and I[A], where I is 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 (Member lookup), method invocation (Method invocations), and indexer access (Indexer access) 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 used to resolve the ambiguities.

在示例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)x).Count(1); // Ok, invokes ICounter.Count

}

}

前两个语句会导致编译时错误,因为成员查找 (成员查找) 的Count中IListCounter不明确。the first two statements cause compile-time errors because the member lookup (Member lookup) of Count in IListCounter is ambiguous. 如示例所示,通过强制转换来解决二义性x为适当的基接口类型。As illustrated 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.

在示例In the example

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); // Invokes IInteger.Add

n.Add(1.0); // Only IDouble.Add is applicable

((IInteger)n).Add(1); // Only IInteger.Add is a candidate

((IDouble)n).Add(1); // Only IDouble.Add is a candidate

}

}

在调用n.Add(1)中选择IInteger.Add通过应用的重载决策规则重载决策。the invocation n.Add(1) selects IInteger.Add by applying the overload resolution rules of Overload resolution. 同样的调用n.Add(1.0)选择IDouble.Add。Similarly the invocation n.Add(1.0) selects IDouble.Add. 插入了显式强制转换,就只有一个候选方法,因此没有歧义。When explicit casts are inserted, there is only one candidate method, and thus no ambiguity.

在示例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

}

}

IBase.F情况下隐藏成员ILeft.F成员。the IBase.F member is hidden by the ILeft.F member. 在调用d.F(1)因此选择ILeft.F,即使IBase.F似乎未隐藏,引导完成的访问路径中IRight。The invocation d.F(1) thus selects ILeft.F, even though IBase.F appears to not be hidden in the access path that leads through IRight.

多个继承接口中的隐藏的直观规则只是这样:如果在任何一个访问路径,则隐藏该成员,它是隐藏在所有的访问路径中。The intuitive rule for hiding in multiple-inheritance interfaces is simply this: If a member is hidden in any access path, it is hidden in all access paths. 因为从的访问路径IDerived到ILeft到IBase隐藏IBase.F,从访问路径中还隐藏该成员IDerived到IRight到IBase。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.

完全限定的接口成员名称Fully qualified interface member names

接口成员有时会通过其完全限定的名称。An interface member is sometimes referred to by its fully qualified name. 接口成员的完全限定的名包含的名称的接口中的成员是声明,跟一个点,然后是的成员的名称。The fully qualified name of an interface member consists of the name of the interface in which the member is declared, followed by a dot, followed by the name of the member. 成员的完全限定的名称引用在其中声明成员的接口。The fully qualified name of a member references the interface in which the member is declared. 例如,给定的声明For example, given the declarations

interface IControl

{

void Paint();

}

interface ITextBox: IControl

{

void SetText(string text);

}

完全限定的名称Paint是IControl.Paint和完全限定的名称SetText是ITextBox.SetText。the fully qualified name of Paint is IControl.Paint and the fully qualified name of SetText is ITextBox.SetText.

在上面的示例中,它不能是指Paint作为ITextBox.Paint。In the example above, it is not possible to refer to Paint as ITextBox.Paint.

如果接口是命名空间的一部分,接口成员的完全限定的名包括命名空间名称。When an interface is part of a namespace, the fully qualified name of an interface member includes the namespace name. 例如For example

namespace System

{

public interface ICloneable

{

object Clone();

}

}

此处,完全限定的名称Clone方法是System.ICloneable.Clone。Here, the fully qualified name of the Clone method is System.ICloneable.Clone.

接口实现Interface implementations

可能由类和结构实现接口。Interfaces may be implemented by classes and structs. 若要指示类或结构直接实现一个接口,类或结构的基列表中包含的接口标识符。To indicate that a class or struct directly implements an interface, the interface identifier is included in the base class list of the class or struct. 例如:For example:

interface ICloneable

{

object Clone();

}

interface IComparable

{

int CompareTo(object other);

}

class ListEntry: ICloneable, IComparable

{

public object Clone() {...}

public int CompareTo(object other) {...}

}

类或结构直接实现的接口直接隐式实现的所有接口的基接口。A class or struct that directly implements an interface also directly implements all of the interface's base interfaces implicitly. 即使类或结构不会显式列出基类列表中的所有基接口,这是如此。This is true even if the class or struct doesn't explicitly list all base interfaces in the base class list. 例如:For example:

interface IControl

{

void Paint();

}

interface ITextBox: IControl

{

void SetText(string text);

}

class TextBox: ITextBox

{

public void Paint() {...}

public void SetText(string text) {...}

}

在这里,类TextBox同时实现IControl和ITextBox。Here, class TextBox implements both IControl and ITextBox.

当类C直接实现一个接口,从 C 派生的所有类还隐式实现接口。When a class C directly implements an interface, all classes derived from C also implement the interface implicitly. 在类声明中指定的基接口可以是构造的接口类型 (构造类型)。The base interfaces specified in a class declaration can be constructed interface types (Constructed types). 基接口不能是自身、 类型参数,但它可能涉及到作用域中的类型参数。A base interface cannot be a type parameter on its own, though it can involve the type parameters that are in scope. 下面的代码演示如何对一个类可以实现和扩展构造的类型:The following code illustrates how a class can implement and extend constructed types:

class C {}

interface I1 {}

class D: C, I1 {}

class E: C, I1 {}

泛型类声明的基接口必须满足唯一性规则中所述实现的接口的唯一性。The base interfaces of a generic class declaration must satisfy the uniqueness rule described in Uniqueness of implemented interfaces.

显式接口成员实现代码Explicit interface member implementations

为了实现接口,类或结构可以声明显式接口成员实现代码。For purposes of implementing interfaces, a class or struct may declare explicit interface member implementations. 显式接口成员实现是引用完全限定的接口成员名称的方法、 属性、 事件或索引器声明。An explicit interface member implementation is a method, property, event, or indexer declaration that references a fully qualified interface member name. 例如For example

interface IList

{

T[] GetElements();

}

interface IDictionary

{

V this[K key];

void Add(K key, V value);

}

class List: IList, IDictionary

{

T[] IList.GetElements() {...}

T IDictionary.this[int index] {...}

void IDictionary.Add(int index, T value) {...}

}

这里IDictionary.this和IDictionary.Add是显式接口成员实现。Here IDictionary.this and IDictionary.Add are explicit interface member implementations.

在某些情况下,接口成员的名称可能不是适用于实现的类,将在其中用例的接口成员可能会实现使用显式接口成员实现。In some cases, the name of an interface member may not be appropriate for the implementing class, in which case the interface member may be implemented using explicit interface member implementation. 类实现文件抽象,例如,可能会实现Close成员函数,释放文件资源的影响并实现了Dispose方法的IDisposable接口使用显式接口成员的实现:A class implementing a file abstraction, for example, would likely implement a Close member function that has the effect of releasing the file resource, and implement the Dispose method 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);

}

}

不能通过在方法调用、 属性访问或索引器访问其完全限定名称访问的显式接口成员实现。It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property access, or indexer access. 显式接口成员实现只能通过接口实例访问,并且在这种情况下引用只需通过其成员名称。An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.

它是显式接口成员实现包括访问修饰符的编译时错误,它会导致编译时错误包含修饰符abstract, virtual, override,或static。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 in a sense private. 但是,由于它们可以通过将接口实例访问,因此可以在某种意义上也是公共。However, since they can be accessed through an interface instance, they are in a sense also public.

显式接口成员实现代码有两个主要用途:Explicit interface member implementations serve two primary purposes:

显式接口成员实现代码不是通过类或结构的实例可访问的因为它们允许接口实现,若要从公共接口的类或结构中排除。Because explicit interface member implementations are not accessible through class or struct instances, they allow interface implementations to be excluded from the public interface of a class or struct. 此功能特别有用,当类或结构实现此类或结构的使用者不感兴趣的内部接口。This is particularly useful when a class or struct implements an internal interface that is of no interest to a consumer of that class or struct.

显式接口成员实现允许消除具有相同签名的接口成员的歧义。Explicit interface member implementations allow disambiguation 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 any implementation at all of interface members with the same signature but with different return types.

有效的显式接口成员实现,类或结构必须命名其基类列表中包含其完全限定的名称、 类型和参数类型完全匹配的显式接口成员的成员的接口实现。For an explicit interface member implementation to be valid, the class or 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. 因此,在下面的类Thus, in the following class

class Shape: ICloneable

{

object ICloneable.Clone() {...}

int IComparable.CompareTo(object other) {...} // invalid

}

声明IComparable.CompareTo会导致编译时错误,因为IComparable的基类列表中未列出Shape并不是基接口的ICloneable。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

}

声明ICloneable.Clone中Ellipse导致编译时错误,因为ICloneable的基类列表中未显式列出Ellipse。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.

接口成员的完全限定的名称必须引用在其中声明成员的接口。The fully qualified name of an interface member must reference the interface in which the member was declared. 因此,在下面的声明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) {...}

}

显式接口成员实现的Paint必须编写为IControl.Paint。the explicit interface member implementation of Paint must be written as IControl.Paint.

实现的接口的唯一性Uniqueness of implemented interfaces

实现泛型类型声明的接口必须保持唯一的所有可能的构造类型。The interfaces implemented by a generic type declaration must remain unique for all possible constructed types. 如果没有此规则,将无法确定要调用的某些构造的类型的正确方法。Without this rule, it would be impossible to determine the correct method to call for certain constructed types. 例如,假设一个泛型类声明了允许按以下方式编写:For example, suppose a generic class declaration were permitted to be written as follows:

interface I

{

void F();

}

class X: I, I // Error: I and I conflict

{

void I.F() {...}

void I.F() {...}

}

如果允许这样,它无法确定要在以下情况下执行的代码:Were this permitted, it would be impossible to determine which code to execute in the following case:

I x = new X();

x.F();

若要确定泛型类型声明的接口列表是否有效,请执行以下步骤:To determine if the interface list of a generic type declaration is valid, the following steps are performed:

让L是直接在泛型类、 结构或接口声明中指定的接口的列表C。Let L be the list of interfaces directly specified in a generic class, struct, or interface declaration C.

将添加到L任何基接口的接口已在L。Add to L any base interfaces of the interfaces already in L.

删除任何重复项L。Remove any duplicates from L.

如果任何可能构造从创建类型C将类型参数会代入后L,会导致在两个接口L完全相同,然后的声明C无效。If any possible constructed type created from C would, after type arguments are substituted into L, cause two interfaces in L to be identical, then the declaration of C is invalid. 确定所有可能的构造的类型时,不会考虑约束声明。Constraint declarations are not considered when determining all possible constructed types.

在类声明中X接口列表上方L组成I和I。In the class declaration X above, the interface list L consists of I and I. 声明无效,因为任何构造具有类型U和V正在相同的类型会导致这两个接口是相同的类型。The declaration is invalid because any constructed type with U and V being the same type would cause these two interfaces to be identical types.

此外,可以在不同的继承级别统一上指定的接口:It is possible for interfaces specified at different inheritance levels to unify:

interface I

{

void F();

}

class Base: I

{

void I.F() {...}

}

class Derived: Base, I // Ok

{

void I.F() {...}

}

此代码是有效的即使Derived同时实现I和I。This code is valid even though Derived implements both I and I. 代码The code

I x = new Derived();

x.F();

调用中的方法Derived,因为Derived有效地重新实现I(接口重新实现)。invokes the method in Derived, since Derived effectively re-implements I (Interface re-implementation).

泛型方法的实现Implementation of generic methods

当泛型方法隐式实现接口方法,提供每个方法类型参数必须是两个声明中的等效 (在任何接口类型参数替换为适当的类型参数),其中的约束方法类型参数进行标识的序号位置,从左到右。When a generic method implicitly implements an interface method, the constraints given for each method type parameter must be equivalent in both declarations (after any interface type parameters are replaced with the appropriate type arguments), where method type parameters are identified by ordinal positions, left to right.

当泛型方法显式实现接口方法时,但是,实现方法上不允许使用任何约束。When a generic method explicitly implements an interface method, however, no constraints are allowed on the implementing method. 相反,约束被继承的接口方法Instead, the constraints are inherited from the interface method

interface I

{

void F(T t) where T: A;

void G(T t) where T: B;

void H(T t) where T: C;

}

class C: I

{

public void F(T t) {...} // Ok

public void G(T t) where T: C {...} // Ok

public void H(T t) where T: string {...} // Error

}

该方法C.F隐式实现I.F。The method C.F implicitly implements I.F. 在这种情况下,C.F不是需要 (也不允许) 来指定该约束T:object由于object是隐式所有类型参数约束。In this case, C.F is not required (nor permitted) to specify the constraint T:object since object is an implicit constraint on all type parameters. 该方法C.G隐式实现I.G由于约束匹配那些在界面中,在接口类型参数替换为相应类型参数之后。The method C.G implicitly implements I.G because the constraints match those in the interface, after the interface type parameters are replaced with the corresponding type arguments. 方法的约束C.H是一个错误因为密封类型 (string这种情况下) 不能用作约束。The constraint for method C.H is an error because sealed types (string in this case) cannot be used as constraints. 由于隐式接口方法实现的约束需要匹配省略该约束也将是一个错误。Omitting the constraint would also be an error since constraints of implicit interface method implementations are required to match. 因此,就无法隐式实现I.H。Thus, it is impossible to implicitly implement I.H. 仅可以使用显式接口成员实现来实现此接口方法:This interface method can only be implemented using an explicit interface member implementation:

class C: I

{

...

public void H(U u) where U: class {...}

void I.H(T t) {

string s = t; // Ok

H(t);

}

}

在此示例中,显式接口成员实现调用具有更严格弱约束的公共方法。In this example, the explicit interface member implementation invokes a public method having strictly weaker constraints. 请注意,从赋值t到s无效,因为T继承的约束T:string,即使此约束不可表示源代码中。Note that the assignment from t to s is valid since T inherits a constraint of T:string, even though this constraint is not expressible in source code.

接口映射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 implementations of interface members in an implementing class or struct is known as interface mapping.

类或结构的接口映射C为每个接口的基的类列表中指定的每个成员定位实现C。Interface mapping for a class or struct C locates an implementation for each member of each interface specified in the base class list of C. 特定的接口成员的实现I.M,其中I是在其中的接口成员M声明,确定通过检查每个类或结构S,从开始C和为每个后续基类重复C,直到找到匹配项:The implementation of a particular interface member I.M, where I is the interface in which the member M is declared, is determined by examining each class or struct S, starting with C and repeating for each successive base class of C, until a match is located:

如果S包含声明的匹配的显式接口成员实现I并M,则此成员是实现I.M。If S contains a declaration of an explicit interface member implementation that matches I and M, then this member is the implementation of I.M.

否则为如果S包含非静态公共成员相匹配的声明M,则此成员是实现I.M。Otherwise, if S contains a declaration of a non-static public member that matches M, then this member is the implementation of I.M. 如果多个匹配项有一个成员,它是未指定哪个成员是实现I.M。If more than one member matches, it is unspecified which member is the implementation of I.M. 这种情况下只能如果S为构造的类型,其中泛型类型中声明的两个成员具有不同的签名,但类型参数可以让它们的签名完全相同。This situation can only occur if S is a constructed type where the two members as declared in the generic type have different signatures, but the type arguments make their signatures identical.

如果实现找不到指定的基类列表中的所有接口的所有成员会发生编译时错误C。A compile-time error occurs if implementations cannot be located for all members of all interfaces specified in the base class list of C. 请注意接口的成员,包括那些继承自基接口的成员。Note that the members of an interface include those members that are inherited from base interfaces.

有关接口映射,类成员的含义A与接口成员匹配B时:For purposes of interface mapping, a class member A matches an interface member B when:

A 并B方法,和名称、 类型和形参表的A和B完全相同。A and B are methods, and the name, type, and formal parameter lists of A and B are identical.

A 和B是属性、 名称和类型的A和B是相同的并且A具有相同的访问器作为B(A允许具有其他访问器,如果它不是显式接口成员实现)。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 explicit interface member implementation).

A 并B是事件,以及名称和类型的A和B完全相同。A and B are events, and the name and type of A and B are identical.

A 和B是索引器、 类型和形参列表A并B是相同的和A具有相同的访问器作为B(A允许具有其他访问器,如果不是显式接口成员实现)。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 additional 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.

在示例In the example

interface ICloneable

{

object Clone();

}

class C: ICloneable

{

object ICloneable.Clone() {...}

public object Clone() {...}

}

ICloneable.Clone的成员C的实现变得Clone中ICloneable因为显式接口成员实现代码优先于其他成员。the ICloneable.Clone member of C becomes the implementation of Clone in ICloneable because explicit interface member implementations take precedence over other members.

如果类或结构实现两个或多个接口包含具有相同的名称、 类型和参数类型的成员,则可以将每个到单个类或结构成员上这些接口成员。If a class or struct implements 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. 例如For example

interface IControl

{

void Paint();

}

interface IForm

{

void Paint();

}

class Page: IControl, IForm

{

public void Paint() {...}

}

在这里,Paint两个方法IControl并IForm映射到Paint中的方法Page。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.

如果类或结构实现包含隐藏的成员的接口,然后某些成员必须通过显式接口成员实现来实现。If a class or struct implements an interface that contains 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 of the following forms

class C: IDerived

{

int IBase.P { get {...} }

int IDerived.P() {...}

}

class C: IDerived

{

public int P { get {...} }

int IDerived.P() {...}

}

class C: IDerived

{

int IBase.P { get {...} }

public int P() {...}

}

当一个类实现多个具有相同的基接口的接口时,可以只有一个基接口的实现。When a class implements multiple interfaces that have the same base interface, there can be only one implementation of the base interface. 在示例In the example

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) {...}

}

不能具有单独实现IControl在基的类列表中,名为IControl由继承ITextBox,和IControl由继承IListBox。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 these interfaces. 相反,实现ITextBox和IListBox共享的相同实现IControl,和ComboBox只需实现三个接口,被视为IControl, ITextBox,和IListBox。Rather, the implementations of ITextBox and IListBox share the same implementation of IControl, and ComboBox is simply considered to implement three interfaces, IControl, ITextBox, and IListBox.

基类的成员参与接口映射。The members of a base class participate in interface mapping. 在示例In the example

interface Interface1

{

void F();

}

class Class1

{

public void F() {}

public void G() {}

}

class Class2: Class1, Interface1

{

new public void G() {}

}

该方法F中Class1中使用Class2的实现Interface1。the method F in Class1 is used in Class2's implementation of Interface1.

接口实现继承Interface implementation inheritance

一个类继承其基类所提供的所有接口实现。A class inherits all interface implementations provided by its base classes.

无需显式重新实现接口,派生的类不能以任何方式更改它从其基类继承的接口映射。Without explicitly re-implementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes. 例如,在声明中For example, in the declarations

interface IControl

{

void Paint();

}

class Control: IControl

{

public void Paint() {...}

}

class TextBox: Control

{

new public void Paint() {...}

}

Paint中的方法TextBox隐藏Paint中的方法Control,但它不会更改的映射Control.Paint拖动到IControl.Paint,以及对调用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 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();

但是,当接口方法映射到类中的虚方法时,就可以为派生类重写虚拟方法并更改接口的实现。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 implementation of the interface. 例如,重写到上面的声明For example, rewriting the declarations above to

interface IControl

{

void Paint();

}

class Control: IControl

{

public virtual void Paint() {...}

}

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();

显式接口成员实现代码不能声明为虚拟函数,因为它不能重写显式接口成员实现。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 explicit interface member implementation to call another method, and that other method can be declared virtual to allow derived classes to override 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() {...}

}

在这里,类派生自Control可以专用化的实现IControl.Paint通过重写PaintControl方法。Here, classes derived from Control can specialize the implementation of IControl.Paint by overriding the PaintControl method.

接口重新实现Interface re-implementation

继承的接口实现的类允许重新实现通过基类列表中包含的接口。A class that inherits an interface implementation is permitted to re-implement the interface by including it in the base class list.

接口重新实现遵循完全相同接口映射的规则的初始实现的接口。A re-implementation of an interface follows exactly the same interface mapping rules as an initial implementation of an interface. 因此,继承的接口映射不起作用的接口映射上建立的重新实现的接口。Thus, the inherited interface mapping has no effect whatsoever on the interface mapping established for the re-implementation of the interface. 例如,在声明中For example, in the declarations

interface IControl

{

void Paint();

}

class Control: IControl

{

void IControl.Paint() {...}

}

class MyControl: Control, IControl

{

public void Paint() {}

}

这一事实,Control映射IControl.Paint拖动到Control.IControl.Paint不会影响在重新实现MyControl,映射IControl.Paint拖到MyControl.Paint。the fact that Control maps IControl.Paint onto Control.IControl.Paint doesn't affect the re-implementation in MyControl, which maps IControl.Paint onto MyControl.Paint.

继承的公共成员声明和继承的显式接口成员声明参与重新实现的接口的接口映射过程。Inherited public member declarations and inherited explicit interface member declarations participate in the interface mapping process for re-implemented interfaces. 例如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() {}

}

此处,实现IMethods中Derived映射到的接口方法Derived.F, Base.IMethods.G, Derived.IMethods.H,并Base.I。Here, the implementation of IMethods in Derived maps the interface methods onto Derived.F, Base.IMethods.G, Derived.IMethods.H, and Base.I.

当类实现一个接口,它隐式还实现了所有该接口的基接口。When a class implements an interface, it implicitly also implements all of that interface's base interfaces. 同样,一个接口重新实现还隐式是重新实现的所有接口的基接口。Likewise, a re-implementation of an interface is also implicitly a re-implementation of all of the interface's base interfaces. 例如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() {...}

}

此处,重新实现IDerived还重新实现IBase映射IBase.F拖动到D.F。Here, the re-implementation of IDerived also re-implements IBase, mapping IBase.F onto D.F.

抽象类和接口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. 例如For example

interface IMethods

{

void F();

void G();

}

abstract class C: IMethods

{

public abstract void F();

public abstract void G();

}

此处,实现IMethods映射F并G到抽象方法,其必须重写的派生自非抽象类中C。Here, the implementation of IMethods maps F and G onto abstract methods, which must be overridden in non-abstract classes that derive from C.

请注意,显式接口成员实现代码不能为抽象的但当然允许显式接口成员实现调用抽象方法。Note that explicit interface member implementations cannot be abstract, but explicit interface member implementations are of course permitted to call abstract methods. 例如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();

}

此处,派生自非抽象类C所需重写FF并GG,从而提供的实际实现IMethods。Here, non-abstract classes that derive from C would be required to override FF and GG, thus providing the actual implementation of IMethods.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值