问题描述
对防止暴露基类表示担忧,我(通过测试)了解到public
类不能从internal
类继承;但是,public
类可以从internal
接口继承.我真的很好奇为什么这是可能的.我认为可能是由于以下原因之一(或任意结合):
While expressing concern with preventing exposure of base classes, I learned (through testing) that a public
class cannot inherit from an internal
class; however, a public
class can inherit from an internal
interface. I am truly curious as to why this is possible. I believe it could be due to one of (or any combination of) the following:
- 接口仅包含必须实现的签名.
- 一个类可能具有可以通过派生类型访问的属性,方法等.
- 类可能具有可以被派生类型覆盖的方法.
案例1
我相信,由于接口只是包含签名的 contract ,并且声明派生类型必须实现这些签名,因此允许继承.这是由于以下事实:接口并不关心谁访问这些签名,而只是派生类型实现了它们.
Case 1
I believe that since an interface is simply a contract that contains signatures and states that derived types must implement those signatures, the inheritance is allowed. This is due to the fact that the interface doesn't care who accesses these signatures, only that the derived type implements them.
与interfaces
不同,类可以具有public
属性,可以通过派生类型访问这些属性.例如:
Unlike interfaces
, classes can have public
properties that can be accessed by derived types. For example:
private class A {
public int SomeProperty { get; set; } = 0;
}
public class B : A {
// Some cool code.
}
public class C : B {
public int MyInt => SomeProperty;
}
由于SomeProperty
是public
,因此该结构的可访问性不一致,并且所有派生类型都可以访问该结构.因此A
和B
必须具有相同的访问级别,以防止暴露.
This structure has inconsistent accessibility since SomeProperty
is public
and can be accessed by all derived types; thus A
and B
must have the same access levels to prevent exposure.
这是为什么public
类可以从internal interface
派生而不能从internal class
派生的原因,还是我错过了什么吗?另外,还有其他原因使之成为可能吗?
Is this the reason why a public
class can derive from an internal interface
but not a internal class
, or am I missing something? Also, are there any other reasons why this is possible?
我不是在寻找基于意见的答案;我正在寻找实现这一目标的技术上正确的原因.
I am not looking for an opinion based answer; I am looking for the technically correct reason why this is possible.
这不是重复的,因为我想知道为什么不能从一个衍生而来的原因,但是你可以从另一个衍生出来.
This is not a duplicate as I wanted the reason why you can't derive from one, but you can another.
推荐答案
我认为您缺少的关键概念是继承与接口实现之间的区别.
I think that the key concept you are missing is the difference between inheritance and interface implementation.
当一个类继承另一个类时,这意味着它基本上是基类的一种更特定的类型-例如,狗是动物的一种特定类型,因此当您拥有这样的类时:
When a class inherits another class, it means it's basically a more specific type of the base class - for instance, a dog is a specific type of an animal, so when you have classes like these:
class Animal {/* implementation here */}
class Dog : Animal {/* dog implementation here */}
Dog
类已经包含Animal的所有实现,除了其构造函数(静态和实例)和Finalizers.
The Dog
class already contains all the implementation of the Animal, except it's constructors (static and instance) and Finalizers.
但是,当一个类实现一个接口时,这意味着它必须提供该接口的成员(即方法,属性,事件和索引器),因此,如果您具有一个IAnimal
接口和一个Dog
类来实现它直接,您的代码如下所示:
However, when a class implements an interface, it means that it must provide the members of said interface (namely method, properties, events and indexers), so if you have an IAnimal
interface and a Dog
class implementing it directly, your code looks like this:
interface IAnimal
{
void Eat();
}
class Dog : IAnimal
{
public void Eat() {/* implementation here */}
}
请注意,必须在Dog
类中显式或隐式地实现IAnimal
声明的所有内容-因此,接口提供的协定将保留在该类中-无论该类的用户是否知道界面与否.
Note that everything that the IAnimal
is declaring must be implemented, explicitly or implicitly, in the Dog
class - so the contract provided by the interface is preserved in the class - regardless of whether the user of the class knows the interface or not.
因此,总而言之-要使用该类,您无需了解其实现的接口的任何信息,但是您确实需要了解该类的所有内容,并且由于Dog是动物,因此如果Dog是公共的,动物也必须如此.
另一方面,IAnimal界面可以保留在内部.
So in conclusion - To use the class you don't need to know anything about the interfaces it implements, but you do need to know everything that is the class, and since a Dog IS an Animal, if the Dog is public, so must be the Animal.
The IAnimal interface, on the other hand, can stay internal.
关于实现内部接口的另一点,已经在user2864740的问题注释中提到-由于所有隐式接口实现都必须是公共的-如果要实现内部接口,则应考虑明确实现-这样,实现就可以在内部保持并且是不会暴露在装配件的外部.
One more point about implementing internal interfaces, already mentioned on the comments to the question by user2864740 - Since all implicit interface implementations must be public - if you are implementing an internal interface, you should consider implementing it explicitly - this way the implementation stays internal and is not exposed outside of the containing assembly.
这篇关于继承:内部类与内部接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!