为什么公共课不能扩展私人课程?

我有一个类的层次结构:

interface Repository // This class contains some common stuff for LocalRepository and RemoteRepository. I'm never going to use this class outside this file, so I make it private private abstract class BasicRepositoryImpl // these classes are designed to be instantiated in other files class LocalRepository : BasicRepositoryImpl(), Repository // error class RemoteRepository : BasicRepositoryImpl(), Repository // error 

但是我得到以下错误:

子类有效可见性“公共”应该与其超类有效可见性“私有”相同或更少,

我不想在其他任何地方使用BasicRepositoryImpl ,所以它被声明为private ,我想在这样的其他文件中使用LocalRepositoryRemoteRepository

 class Presenter(val repo: Repository) val p = Presenter(LocalRepository()) 

但是那个错误阻止我创建这样一个层次结构。 为什么? 它出什么问题了?

class级及其祖先必须全部都可以从使用类访问。 否则,在加载祖先类时,不仅会调用它的方法或使用它的function,这将是一个违规行为。 在所有情况下,Kotlin都非常干净清晰。

稍微打开它会允许事后可能导致真正的JVM访问冲突,比如公共类中的inline函数,内联到另一个类中,调用祖先的私有的不可访问的东西 。 如果你觉得可以像这样做一个可访问性的混合模型,那么你不会考虑很多漏洞。 考虑因素的矩阵大于只隐藏某些类实例化的欲望。

由于课程是抽象的,除了作为祖先之外不能直接使用,所以你已经有了一些保护。 如果你想阻止你的模块之外的祖先使用,使其构造函数privateinternal ,这将解决这个问题:

 abstract class BasicRepositoryImpl private constructor() { ... } 

现在,您已经保护了直接实例化( abstract )或作为基类(通过使用abstract和私有构造函数),所以最后要做的就是给它一个像AbstractBaseRepository这样的好名字,人们将按照惯例离开它。

如果你想讨论“为什么”这是设计决定,或技术限制,或保护规则…然后尝试在YouTrack 讨论论坛 ,function或语言变化的建议。 但是要小心,事情并不像看起来那么简单。 这些规则是有原因的( 即使其他语言危险地允许 )。

只做抽象类

定义:抽象类是一个被声明为抽象的类 – 它可能包含也可能不包含抽象方法。 抽象类不能被实例化,但它们可以被子类化。