为什么在C#中,派生类不允许具有比其基类更大的可访问性。
例如,这将给出错误:不一致的可访问性:基类'BaseClass'比类'DerivedClass'更难访问
internal class BaseClass
{
}
public class DerivedClass : BaseClass
{
}
为什么它在Java中被允许。
答案 0 :(得分:11)
更新:此问题为the subject of my blog on November 13th 2012。谢谢你提出的好问题!
为什么在C#中,派生类不允许具有比其基类更大的可访问性?
除了其他好的答案外,请考虑这种情况。你和你的同事爱丽丝正在研究同一组件的不同部分。爱丽丝写了一堂课:
public class ComplicatedClass
{
public void DoDangerousThing() { ... }
}
然后你写
public class EvenMoreComplicatedClass : ComplicatedClass
{
}
大。现在,Alice从Bob获得安全审查,并且他们意识到(1)没有客户需要使用ComplicatedClass,以及(2)DoDangerousThing暴露了恶意代码可以利用的安全漏洞。内部代码当然没有。
所以Alice将她的代码更改为
internal class ComplicatedClass
{
public void DoDangerousThing() { ... }
}
确定没有必要在方法上将“公共”更改为“内部”,因为当然公共意味着“公开可以看到这个类的东西”,现在没有外部代码可以看到这个类。
当Alice使用此更改重新编译时,您的代码会发生什么? 它应该无法编译。您假设用户需要查看基类,并且Alice已做出违反该假设的更改。安全的做法是让编译器告诉Alice她需要和你谈谈,这样你就可以解决这个问题,而不会让客户暴露在DoDangerousThing的漏洞中。
为什么Java中允许它?
不知道,抱歉。
答案 1 :(得分:9)
这样,使用标记为internal或private的类就像公共一样,只需执行空覆盖,就像在示例中一样。这样就无法将除了公开之外的任何东西标记为类别。
答案 2 :(得分:2)
internal
与Java中的package private
不同。 DerivedClass
的用户可能没有或无法访问BaseClass
所在的DLL,因此DerivedClass
无法依赖它。在Java中,包隐私是一个更宽松的概念 - 但在您的示例中,DerivedClass
必须与BaseClass
位于同一个包中,因此客户端用户很可能拥有这两个类,因此Java允许它。
答案 3 :(得分:0)
因为否则您将比预期更多地暴露BaseClass成员。
问题的一个例子是public const int Age
。这是可以的,因为它只在同一个程序集中公开,因此版本控制是安全的。如果现在使用inheritence使类公开,那么您将在constcily之外公开此const字段。如果值发生变化,这可能会导致错误。
我经常在内部制作一个类,这样我就不用担心将来版本化它的公共接口了。我可以随时更改它,只要那个程序集合就可以了。如果有人出现并公开曝光,我现在必须永远重新审视公共界面。