java - 限制 C# 中抽象基类的可见性

标签 java c# interface abstract privacy

我觉得这个问题可能因为主观而偏离主题,但我很好奇。

在 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 种方式对子类进行分组:AMyClassIMyClass 类型。这看起来真的很草率,特别是如果我想为不同类型的 IMyClass 创建另一个 abstract 基类。在这种情况下,现在将公开 2 个抽象类,我不希望其他项目使用它们。

有没有办法阻止其他项目使用抽象类,或者只是将其放入项目文档中并依赖某种荣誉系统

最佳答案

这取决于你想要什么。您是否想禁止程序集外部的客户端代码全部使用抽象基类?或者您只是想阻止从此类代码继承它?

后者可以简单地通过将构造函数设为内部来实现。这可以防止程序集外部的任何代码能够继承它,因为它们无权访问构造函数。 (请注意,对于非抽象类,您还可以通过将构造函数设置为protectedprivate来防止直接实例化......显然没有必要这样做与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/

相关文章:

java - 需要帮助以在一定延迟后从 Web URL 下载文件

java - 在二叉树上递归搜索

c# - VSTO 将图像插入到 Outlook 中的 Word、Excel、PowerPoint 和邮件附件中

c# - Asp.Net Core 2.0 中的“HttpPostedFileBase”

c# - 找到字符串后拆分大型 XML 文件

c# - 同一个方法的两个接口(interface)

c# - 为什么 C# 在明知自己没有结构类型的情况下还要取笑结构类型?

java - hadoop没有将输出写入文件

java - PropertyPlaceholderConfigurer 用于查找数据库值并使用属性文件作为后备

java - 向实现类添加功能而不更改实现的接口(interface)