c#多接口继承不允许具有相同名称的公共访问修饰符
本文关键字:访问 继承 接口 不允许 | 更新日期: 2023-09-27 18:02:34
这让我很困惑。
假设有两个接口。
public interface a
{
void foo();
}
public interface b
{
void foo();
}
这两个接口都有一个函数foo,我有一个提供显式实现的类:
public class alpha : a, b
{
// why can't I put an access modifier here?
// How would you be able to hide this from a derived class
void a.foo()
{
Console.WriteLine("a");
}
void b.foo()
{
Console.WriteLine("b");
}
}
和从alpha
派生的Classpublic class beta : alpha
{
}
如何使foo私有或受保护,因为alpha不允许显式实现的访问修饰符,什么可以阻止别人调用:
var be = new beta();
(be as b).foo();
编辑
为什么当我不显式地提供实现时,我可以提供访问修饰符?
public class alpha : a, b
{
//why this compile?
public void foo()
{
Console.WriteLine("both");
}
}
由于接口a
是公共的,任何实现a
的类必须使a
的方法可以隐式(通过公共方法)或显式地公开访问。显式实现是"某种程度上"私有的,因为它们只能通过接口访问。
简而言之,没有办法完全"隐藏"foo
-你的类实现了a
和b
,所以这些方法必须通过某种方式使可以访问。
也是正确的——具有方法名称冲突的多个接口只会迫使您使实现显式。如果你有一个接口,foo
要么必须是public
,要么是显式的。
什么可以阻止某人打电话
没什么,这就是重点!
beta
是b
,因此您可以将其视为b
。如果您选择将其强制转换为b
并调用显式foo
实现,您将获得b
实现。
如其他答案所示,这些是语言的规则,必须遵守。
示例说明为什么需要在接口实现中显式指定public
:
class Base
{
protected void Foo() { }
}
public interface IFoo
{
void Foo();
}
类Base
显式地选择不向类的用户公开方法Foo
(除了派生,也可以是private
)。
现在,如果另一个类想从Base
派生并同时实现IFoo
。如果语言允许只选择实现而不考虑访问修饰符,这将意味着Base.Foo
现在由派生向每个调用者公开:
class Derived : Base, IFoo
{
// hypothetical compiler allows to pick any matching `void Foo`
// including inherited `protected void Base.Foo()`
}
这显然违背了Base
类隐藏Foo
方法的意图-因此语言必须要求Foo
成为public
才能被视为接口的一部分。
作为结果,你结束了"可选的"访问修饰符在接口实现中,你只有一个选项-必须指定public
。
请注意,Derived
有两个选项来处理Foo
-显式实现和new
的阴影:
class Derived : Base, IFoo
{
new public void Foo() {}
}