【问题标题】:Inheritance: Internal Class vs. Internal Interface继承:内部类与内部接口
【发布时间】:2018-10-16 20:36:20
【问题描述】:

在表达对preventing exposure of base classes 的关注时,我了解到(通过测试)public 类不能从internal 类继承;但是,public 类可以从internal 接口继承。我真的很好奇为什么这是可能的。我相信这可能是由于以下之一(或任何组合):

  1. 接口只包含必须实现的签名。
  2. 类可能具有可通过派生类型访问的属性、方法等。
  3. 一个类可能有可以被派生类型覆盖的方法。

案例一

我相信,由于接口只是一个契约,其中包含签名并声明派生类型必须实现这些签名,因此允许继承。这是因为接口不关心谁访问了这些签名,只关心派生类型实现它们。


案例 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 的原因,还是我遗漏了什么?另外,还有什么其他原因可以做到这一点吗?


注意

我不是在寻找基于意见的答案;我正在寻找技术上正确的原因。

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

【问题讨论】:

  • 注意:公共类不能从隐式实现的内部接口中导出。
  • 似乎有点回避这个问题。公共类不允许实现内部类即使没有一个内部类成员是非内部的。所以限制发生在替换之前(并且更普遍)。
  • @CSharper 虽然读得很好,但它确实没有回答我的问题。
  • @user2864740 如果我的理解正确,public class 必须显式实现接口才能工作?

标签: c# inheritance


【解决方案1】:

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

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

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 接口可以保留在内部。

关于实现内部接口的另一点,已经在 cmets 中提到了 user2864740 的问题 - 由于所有隐式接口实现都必须是公共的 - 如果您正在实现内部接口,您应该考虑 implementing it explicitly - 这样实现保持在内部,不暴露在包含程序集之外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 2011-12-21
    • 1970-01-01
    相关资源
    最近更新 更多