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

Java 限制C中抽象基类的可见性#,java,c#,interface,abstract,privacy,Java,C#,Interface,Abstract,Privacy,我觉得这个问题可能是主观的,但我很好奇 在java中,我习惯于使用包private和public对其他包隐藏类型的实现。我通常有一个界面,例如: public interface IMyClass { ... } 然后在同一个包中的私有抽象类中定义IMyClass实现的任何通用功能 abstract class AMyClass implements IMyClass { public AMyClass(...) ... } 然后派生类型是public,也在IMyCl

我觉得这个问题可能是主观的,但我很好奇

在java中,我习惯于使用包private和public对其他包隐藏类型的实现。我通常有一个
界面
,例如:

public interface IMyClass {
    ...
}
然后在同一个包中的私有
抽象类中定义
IMyClass
实现的任何通用功能

abstract class AMyClass implements IMyClass {
    public AMyClass(...)
    ...
}
然后派生类型是
public
,也在
IMyClass
包中定义

public class CustomMyClass extends AMyClass {
    public CustomMyClass(...){
        super(...) 
        ...
}

在c#中,我希望遵循相同的结构,但是当扩展
抽象类时,它必须是
public
。我能找到的防止其他包扩展
AMyClass
或使用其内部函数的唯一方法是使它们的访问级别
内部

public interface IMyClass{
    ...
}
...
public class AMyClass : IMyClass {
    internal AMyClass(...)
    ...
}
...
public class CustomMyClass : AMyClass {
    public CustomMyClass(...) : base(...){
        ...
}
但这种风格仍然允许其他c#projects以两种方式对子类进行分组,
AMyClass
IMyClass
类型。这看起来非常草率,特别是如果我想为不同类型的
IMyClass
创建另一个
abstract
基类。在这种情况下,现在将有2个抽象类公开,我不希望其他项目使用它们


有没有办法阻止其他项目使用抽象类,或者只是简单地放在项目文档中,依靠某种荣誉体系?

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

后者可以简单地通过使构造函数内部化来实现。这会阻止程序集之外的任何代码继承它,因为它们无权访问构造函数。(请注意,对于非
抽象类
类,还可以通过使构造函数
受保护
私有
来防止直接实例化……显然没有必要对
抽象类
执行此操作,因为无论如何都不能直接实例化类)

如果前一种说法是正确的,即C#没有Java的“包”概念,与Java相比,它限制了访问限制的可能性,那么您可以接近

派生类不能比其基类更容易访问。这意味着
public
类的基类(
abstract
或其他)本身必须是
public

但是,通过使
抽象
内部
(即C#中的类的默认访问权限),然后使继承它的类也
内部
,您可以实现隐藏在C#中的基于接口的实现,就像在Java中一样,在保留接口的同时,这些类实现了
public
,这为使用库的客户机代码提供了一种访问类的公共特性的方法


由于使基类
为内部
会阻止您使派生类
为公共
,因此库的客户端也无法直接创建派生类的实例。因此,在某个公共类中必须有一个公共工厂方法,该方法返回公共接口,而不是派生类。

我不明白这个问题。由于缺乏“包”的概念,C语言中的类不能是
private
,而
抽象类必须是
public
,这是事实。您可以在同一程序集中继承一个
内部抽象
类和另一个
内部
类,实现一个
公共
接口,该接口是外部世界唯一可见的东西。这似乎与您在Java中所做的相同,对吗?@PeterDuniho如果我将
AMyClass
设置为
internal abstract class
,我会得到错误“基类AMyClass的可访问性不如CustomMyClass”@但是如果我把实现也设置为内部的,我想我必须创建一个工厂来构建它们?正确。继承器不能比基类更容易访问,因此需要一个工厂。您可以通过将所有构造函数标记为内部或私有来阻止其他人从
AMyClass
继承。要从类继承,您必须至少可以访问一个构造函数。