我觉得这个问题可能偏离主题,但我很好奇。
在java中,我习惯使用包private和public来隐藏其他包中的类型实现。我通常有一个interface
,例如:
public interface IMyClass {
...
}
IMyClass
实现的任何常见功能都在同一个包中的私有abstract class
中定义
abstract class AMyClass implements IMyClass {
public AMyClass(...)
...
}
然后派生类型为public
,并且也在IMyClass
包
public class CustomMyClass extends AMyClass {
public CustomMyClass(...){
super(...)
...
}
在c#中我想遵循相同的结构,但当你扩展abstract class
时,它必须是public
。我唯一能阻止其他软件包扩展AMyClass
或使用其内部函数的方法是使其访问级别为internal
。
public interface IMyClass{
...
}
...
public class AMyClass : IMyClass {
internal AMyClass(...)
...
}
...
public class CustomMyClass : AMyClass {
public CustomMyClass(...) : base(...){
...
}
但是这种风格仍然允许其他c#项目以2种方式对子类AMyClass
或IMyClass
类型进行分组。这似乎非常草率,特别是如果我想为不同类型的abstract
创建另一个IMyClass
基类。在这种情况下,现在将公开2个抽象类,我不希望其他项目使用。
有没有办法阻止其他项目使用抽象类,或者它只是放在项目文档中并依赖于各种荣誉系统的东西?
答案 0 :(得分:2)
这取决于你想要什么。您是否希望通过程序集外的客户端代码禁止所有使用基础abstract
类?或者你只是想阻止它从这样的代码继承?
后者可以通过制作构造函数internal
来实现。这可以防止程序集外的任何代码继承它,因为它们无法访问构造函数。 (请注意,对于非abstract
类,您还可以通过构造函数protected
或private
来阻止直接实例化...显然,abstract
无需执行此操作因为无论如何都无法直接实例化。)
如果前者是正确的,那么C#没有Java#" package"的概念,这限制了与Java相比可访问限制的可能性,你可以来关闭。
派生类不能比其基类更易于访问。这意味着abstract
类的基类(public
或其他)本身必须为public
。
但您可以通过制作abstract
类internal
(即默认访问权限)来完成与C#中相同类型的基于接口的实现 - 隐藏在C#中C#中的类,然后是一个继承它的类internal
,同时仍然留下一个接口,这些类实现public
,它使用库提供客户端代码来访问类的公共特性。
由于使基类internal
阻止您创建派生类public
,因此您的库的客户端无法直接创建派生类的实例。因此,您必须在某个公共类中使用公共工厂方法,该方法返回公共接口而不是派生类。