C# 多接口继承不允许 public 具有相同名称的访问修饰符
C# Multiple Interface Inheritance does not allow public access modifier with same name
所以这让我很困惑。
假设有两个接口。
public interface a
{
void foo();
}
public interface b
{
void foo();
}
这两个接口都有一个函数 foo,我有一个 class 提供显式实现:
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
派生的 Class
public 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");
}
}
what can stop someone from calling
没什么,这就是重点!
beta
是 b
,因此您可以将其视为 b
。如果您选择将其转换为 b
并调用显式 foo
实现,您将获得 b
实现。
由于接口 a
是 public,任何实现 a
的 class 必须使 a
public 的方法可以访问,隐式(通过 public 方法)或显式。显式实现是 "sort-of" 私有的,因为它们只能通过接口访问。
简而言之,没有办法完全"hide" foo
- 你的class实现了a
和b
所以这些方法 必须 我可以通过某些方式访问。
即使您只有 一个 接口也是如此 - 具有多个具有方法名称冲突的接口只会迫使您明确实现。如果只有一个接口,foo
要么必须是 public
要么是显式的。
如其他答案所示,这些是语言规则,必须遵守。
显示为什么需要在接口实现上明确指定 public
的示例:
class Base
{
protected void Foo() { }
}
public interface IFoo
{
void Foo();
}
Class Base
明确选择不向 class 的用户公开方法 Foo
(派生除外,也可能是 private
)。
现在如果另一个 class 想要从 Base
派生并同时实现 IFoo
。如果语言允许只选择实现而不考虑访问修饰符,则意味着 Base.Foo
现在由 derived 暴露给每个调用者:
class Derived : Base, IFoo
{
// hypothetical compiler allows to pick any matching `void Foo`
// including inherited `protected void Base.Foo()`
}
这显然违背了 Base
class 隐藏 Foo
方法的意图 - 因此语言必须要求 Foo
为 public
被视为接口的一部分。
结果你在接口实现上得到了 "optional" 访问修饰符,你只有一个选项 - 必须指定 public
.
请注意 Derived
有几个选项可以处理 Foo
- 使用 new
的显式实现和阴影:
class Derived : Base, IFoo
{
new public void Foo() {}
}
所以这让我很困惑。
假设有两个接口。
public interface a
{
void foo();
}
public interface b
{
void foo();
}
这两个接口都有一个函数 foo,我有一个 class 提供显式实现:
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");
}
}
what can stop someone from calling
没什么,这就是重点!
beta
是 b
,因此您可以将其视为 b
。如果您选择将其转换为 b
并调用显式 foo
实现,您将获得 b
实现。
由于接口 a
是 public,任何实现 a
的 class 必须使 a
public 的方法可以访问,隐式(通过 public 方法)或显式。显式实现是 "sort-of" 私有的,因为它们只能通过接口访问。
简而言之,没有办法完全"hide" foo
- 你的class实现了a
和b
所以这些方法 必须 我可以通过某些方式访问。
即使您只有 一个 接口也是如此 - 具有多个具有方法名称冲突的接口只会迫使您明确实现。如果只有一个接口,foo
要么必须是 public
要么是显式的。
如其他答案所示,这些是语言规则,必须遵守。
显示为什么需要在接口实现上明确指定 public
的示例:
class Base
{
protected void Foo() { }
}
public interface IFoo
{
void Foo();
}
Class Base
明确选择不向 class 的用户公开方法 Foo
(派生除外,也可能是 private
)。
现在如果另一个 class 想要从 Base
派生并同时实现 IFoo
。如果语言允许只选择实现而不考虑访问修饰符,则意味着 Base.Foo
现在由 derived 暴露给每个调用者:
class Derived : Base, IFoo
{
// hypothetical compiler allows to pick any matching `void Foo`
// including inherited `protected void Base.Foo()`
}
这显然违背了 Base
class 隐藏 Foo
方法的意图 - 因此语言必须要求 Foo
为 public
被视为接口的一部分。
结果你在接口实现上得到了 "optional" 访问修饰符,你只有一个选项 - 必须指定 public
.
请注意 Derived
有几个选项可以处理 Foo
- 使用 new
的显式实现和阴影:
class Derived : Base, IFoo
{
new public void Foo() {}
}