![](/img/trans.png)
[英]C# interface method declared in Base class need not be again implemented in Derived class
[英]Do I need to specify interface implemented by a base class in the definition of a derived class?
在C#中,假設類C1實現接口I1,並且類C2從C1派生。
同樣的問題,如果在C1的聲明中,I1是否具有類型實參,並且該類型實參對於C1和C2是否不同?
例如,
public abstract class C1: I1<C1> public class C2: C1, I1<C2>
我需要在C2的定義中寫I1嗎?
謝謝。
IEnumerable<int>
是與IEnumerable<string>
完全不同的類型 , IEnumerable<string>
最可能需要派生類實現具有與基類不同的簽名的方法。 例:
public interface IGenericInterface<T>
{
T GetSomething();
void DoSomething(T arg);
}
public class BaseClass : IGenericInterface<int>
{
public virtual int GetSomething() { return 5; }
public virtual void DoSomething(int arg) { Console.WriteLine(arg); }
}
public class Derived : BaseClass, IGenericInterface<string>
{
string IGenericInterface<string>.GetSomething() { return "hello world!"; }
public void DoSomething(string arg) { Console.WriteLine(arg); }
}
請注意,在此示例中,需要顯式實現 Derived.GetSomething()
,因為否則它將與基類的int
版本沖突。 具有相同名稱的方法不允許僅在返回類型上有所不同。
如果基類實現某些接口,則不必在派生類中重新實現它。
考慮到正常的用例,答案通常是“否”。 但是,在某些情況下,您應該再次聲明接口。 當您要修改行為時。 考慮以下代碼:
public interface IHello { string SayHello(); } public class Foo : IHello { public string SayHello() => "Foo says hello!"; } public class DerivedFoo : Foo { } public class AnotherDerivedFoo : Foo, IHello { string IHello.SayHello() => "AnotherDerivedFoo says hello!"; }
現在:
IHello foo = new Foo(); IHello derivedFoo = new DerivedFoo(); IHello anotherDerivedFoo = new AnotherDerivedFoo(); Console.WriteLine(foo.SayHello()); //prints "Foo says hello!" Console.WriteLine(derivedFoo.SayHello()); //prints "Foo says hello!" Console.WriteLine(anotherDerivedFoo.SayHello()); //prints "AnotherDerivedFoo says hello!" !!!
您的問題可能涉及Foo
和DerivedFoo
但是該語言的一個鮮為人知的功能是AnotherDerivedFoo
,您可以在其中基本上以不同的行為重新實現接口。
但是請注意以下幾點:
var anotherDerivedFoo = new AnotherDerivedFoo(); //reference is typed AnotherDerivedFoo Console.WriteLine(anotherDerivedFoo.SayHello()); //prints "Foo says hello!"
這是由於您無法重新實現接口的隱式實現。
是的,您必須同時聲明兩者。 請注意,雖然,現在C2
將同時實現I1<C1>
和I1<C2>
一個不取消其他的,他們是,所有的目的,兩個不同的接口。
這可能會導致不幸的情況:
public interface I1<T> { string Foo(T fooable); } public class C1: I1<int> { public string Foo(int i) => "C1.Foo called"; } public class C2: C1, I1<double> { public string Foo(double d) => "C2.Foo called"; }
現在:
var c2 = new C2(); Console.WriteLine(c2.Foo(1)); //C2.Foo(double d) is called, //not C1.Foo(int i)!
所以要小心!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.