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