继承:内部类与内部接口



在表达对防止基类暴露的担忧时,我(通过测试(了解到public类不能从internal类继承;但是,public类可以从internal接口继承。我真的很好奇为什么这是可能的。我相信这可能是由于以下原因之一(或任意组合(:

  1. 接口仅包含必须实现的签名。
  2. 类可能具有可通过派生类型访问的属性、方法等。
  3. 类可能具有可由派生类型重写的方法。

案例1

我相信,由于接口只是一个包含签名的协定,并且派生类型必须实现这些签名,因此允许继承。这是因为接口不关心谁访问这些签名,只关心派生类型实现它们。


案例2和3

interfaces不同,类可以具有派生类型可以访问的public属性。例如:

private class A {
public int SomeProperty { get; set; } = 0;
}
public class B : A {
// Some cool code.
}
public class C : B {
public int MyInt => SomeProperty;
}

此结构具有不一致的可访问性,因为SomePropertypublic并且可以由所有派生类型访问;因此AB必须具有相同的访问级别以防止暴露。


这就是为什么public类可以从internal interface而不是internal class派生的原因,还是我错过了什么?另外,还有其他原因可以做到这一点吗?


注意

我不是在寻找基于意见的答案;我正在寻找技术上正确的原因,为什么这是可能的。

这不是重复的,因为我想要为什么你不能从一个派生,但你可以从另一个派生。

我认为您缺少的关键概念是继承和接口实现之间的区别。

当一个类继承另一个类时,这意味着它基本上是基类的更具体类型 - 例如,狗是动物的特定类型,所以当你有这样的类时:

class Animal {/* implementation here */}
class Dog : Animal {/* dog implementation here */}

Dog类已经包含 Animal 的所有实现,除了它的构造函数(静态和实例(和终结器。

但是,当一个类实现一个接口时,这意味着它必须提供所述接口的成员(即方法、属性、事件和索引器(,所以如果你有一个IAnimal接口和一个直接实现它的Dog类,你的代码看起来像这样:

interface IAnimal 
{
void Eat();
}
class Dog : IAnimal 
{
public void Eat() {/* implementation here */}
}

请注意,IAnimal声明的所有内容都必须在Dog类中显式或隐式实现 - 因此接口提供的协定保留在类中 - 无论类的用户是否知道接口。

所以总而言之 - 要使用类,你不需要知道它实现的接口的任何信息,但你确实需要知道类的所有内容,并且由于狗是动物,如果狗是公共的,那么必须是动物。
另一方面,IAnimal 接口可以保持内部。

关于实现内部接口的另一点,已经在 user2864740 对问题的评论中提到 - 由于所有隐式接口实现都必须是公共的 - 如果要实现内部接口,则应考虑显式实现它 - 这样实现将保持内部,不会在包含程序集之外公开。

最新更新