Читайте также: |
|
· При определении члена класса или структуры, реализующего член интерфейса, явные реализации члена интерфейса имеют приоритет по сравнению с другими членами того же класса или структуры.
· В сопоставлении интерфейсов не участвуют члены, которые являются статическими или не относятся к открытым.
В этом примере
interface ICloneable
{
object Clone();
}
class C: ICloneable
{
object ICloneable.Clone() {...}
public object Clone() {...}
}
реализацией метода Clone интерфейса ICloneable становится член ICloneable.Clone класса C, поскольку явные реализации имеют приоритет по отношению к другим членам.
Если в классе или структуре реализуется два или более интерфейса, содержащих член с одинаковым именем, типом и типами параметров, можно сопоставить каждый из таких членов интерфейса единственному члену класса или структуры. Пример:
interface IControl
{
void Paint();
}
interface IForm
{
void Paint();
}
class Page: IControl, IForm
{
public void Paint() {...}
}
В этом примере методу Paint класса Page сопоставляются методы Paint как класса IControl, так и класса IForm. Разумеется, для каждого из этих двух методов можно создать отдельную явную реализацию члена интерфейса.
Если в классе или структуре реализуется интерфейс, который содержит скрытые члены, некоторые члены необходимо реализовать с использованием явных реализаций члена интерфейса. Например:
interface IBase
{
int P { get; }
}
interface IDerived: IBase
{
new int P();
}
Для реализации этого интерфейса потребуется по меньшей мере одна явная реализация члена интерфейса в одной из приведенных ниже форм:
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() {...}
}
Если в классе реализуется несколько интерфейсов с одним базовым интерфейсом, может существовать только одна реализация этого базового интерфейса. В этом примере
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. Для этих интерфейсов отсутствует указание на их различие. Наоборот, в реализациях интерфейсов ITextBox и IListBox используется одна и та же реализация интерфейса IControl, а класс ComboBox просто считается реализующим три интерфейса: IControl, ITextBox и IListBox.
Члены базового класса участвуют в сопоставлении интерфейсов. В этом примере
interface Interface1
{
void F();
}
class Class1
{
public void F() {}
public void G() {}
}
class Class2: Class1, Interface1
{
new public void G() {}
}
метод F в классе Class1 используется в реализации интерфейса Interface1 в классе Class2.
13.4.5 Наследование реализаций интерфейсов
Класс наследует все реализации интерфейсов, содержащиеся в его базовых классах.
Без явной повторной реализации интерфейса, в производном классе нельзя изменить сопоставление интерфейсов, унаследованных им из базовых классов. Например, в объявлениях
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 в экземплярах класса и экземплярах интерфейса приведет к следующим результатам
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();
Тем не менее, при сопоставлении метода интерфейса с виртуальным методом в классе можно переопределить этот виртуальный метод в производных классах и изменить реализацию интерфейса. Например, изменение записи приведенных выше объявлений на
interface IControl
{
void Paint();
}
class Control: IControl
{
public virtual void Paint() {...}
}
class TextBox: Control
{
public override void Paint() {...}
}
приведет к следующим результатам:
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();
Так как явные реализации метода интерфейса не могут быть объявлены виртуальными, переопределить явную реализацию члена интерфейса невозможно. Однако в явной реализации члена интерфейса можно вызвать другой метод, который может быть объявлен виртуальным, что позволяет переопределить его в производных классах. Пример:
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.
13.4.6 Повторная реализация интерфейса
В классе, который наследует реализацию интерфейса, разрешается повторно реализовать этот интерфейс путем включения его в список базовых классов.
Для повторной реализации интерфейса действуют такие же правила сопоставления интерфейсов, что и для первой реализации интерфейса. Таким образом, унаследованное сопоставление интерфейсов не влияет на сопоставление интерфейсов, установленное в повторной реализации этого интерфейса. Например, в объявлениях
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.
В процедуре сопоставления повторно реализованных интерфейсов участвуют унаследованные объявления открытых членов и унаследованные явные объявления членов интерфейса. Например:
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.
При реализации интерфейса в классе также неявно реализуются все базовые интерфейсы этого интерфейса. Аналогичным образом повторная реализация интерфейса неявно является повторной реализацией всех базовых интерфейсов этого интерфейса. Пример:
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.
Дата добавления: 2015-11-14; просмотров: 54 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
GetEnumerator 5 страница | | | AttributeUsage |