在表达关切的同时防止基类暴露 https://stackoverflow.com/questions/52842532/prevent-exposure-of-base-classes-abstract-classes/52843168#52843168,我了解到(通过测试)public
类不能继承自internal
班级;然而,一个public
类可以继承自internal
界面。我真的很好奇为什么这是可能的。我认为这可能是由于以下原因之一(或任意组合)造成的:
- 接口仅包含必须实现的签名。
- 类可能具有可通过派生类型访问的属性、方法等。
- 类可能具有可由派生类型重写的方法。
Case 1
我相信,由于接口只是一个contract包含签名并声明派生类型必须实现这些签名,则允许继承。这是因为接口并不关心谁访问这些签名,只关心派生类型实现它们。
案例2和案例3
Unlike 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;
}
此结构具有不一致的可访问性,因为SomeProperty
is public
并且可以被所有派生类型访问;因此A
and B
必须具有相同的访问级别以防止暴露。
这就是为什么public
类可以派生自internal interface
但不是internal class
,或者我错过了什么?另外,还有其他原因可以实现这一点吗?
Note
我不是在寻找基于意见的答案;我正在寻找技术上正确的原因来解释为什么这是可能的。
这不是重复的,因为我想知道为什么你不能从一个派生,但你可以从另一个派生。
我认为您缺少的关键概念是继承和接口实现之间的区别。
当一个类继承另一个类时,这意味着它基本上是基类的更具体类型 - 例如,狗是动物的特定类型,因此当您有这样的类时:
class Animal {/* implementation here */}
class Dog : Animal {/* dog implementation here */}
The Dog
类已经包含 Animal 的所有实现,除了它的构造函数(静态和实例)和终结器。
然而,当一个类实现一个接口时,就意味着它必须提供该接口的成员(即方法、属性、事件和索引器),所以如果你有一个IAnimal
接口和一个Dog
直接实现它的类,您的代码如下所示:
interface IAnimal
{
void Eat();
}
class Dog : IAnimal
{
public void Eat() {/* implementation here */}
}
请注意,所有内容IAnimal
声明必须显式或隐式地实现Dog
类 - 因此接口提供的契约保留在类中 - 无论类的用户是否知道该接口。
所以总而言之 - 要使用该类,您不需要了解它实现的接口的任何信息,但您确实需要了解该类的所有内容,并且由于狗是动物,如果狗是公共的,那么必须成为动物。
另一方面,IAnimal 接口可以保留在内部。
关于实现内部接口的另一点,已经在 user2864740 对问题的评论中提到 - 由于所有隐式接口实现必须是公共的 - 如果您正在实现内部接口,您应该考虑明确实施 https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation- 这样,实现就保留在内部,并且不会暴露在包含程序集之外。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)