问题
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:
- An interface simply contains signatures that must be implemented.
- A class may have properties, methods, etc. that can be accessed via the derived type.
- A class may have methods that can be overridden by derived types.
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.
Case 2 and 3
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;
}
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.
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?
Note
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.
回答1:
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 */}
The Dog class already contains all the implementation of the Animal, except it's constructors (static and instance) and Finalizers.
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 */}
}
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.
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.
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.
来源:https://stackoverflow.com/questions/52843692/inheritance-internal-class-vs-internal-interface