kotlin 为什么public class不能扩展private class?

3df52oht  于 2023-10-23  发布在  Kotlin
关注(0)|答案(3)|浏览(148)

我有一个如下的类层次结构:

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

但我得到以下错误:
子类有效可见性'public'应该与它的超类有效可见性'private'相同或更不允许
我不想在其他地方使用BasicRepositoryImpl,所以它被声明为private,我想在其他文件中使用LocalRepositoryRemoteRepository,如下所示:

class Presenter(val repo: Repository)

val p = Presenter(LocalRepository())

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

s6fujrry

s6fujrry1#

类及其祖先必须all可从using类访问。否则,在加载祖先类时,而不仅仅是调用它的方法或使用它的功能时,这将是一个违规行为。Kotlin在所有存在可访问性的情况下都非常干净和清晰。
稍微打开它会允许一些可能导致真实的JVM访问冲突的东西,比如公共类中的inline函数,内联到另一个类中,调用祖先的私有不可访问 something。如果你觉得做一个像这样的可访问性的混合模型是可以的,那么你没有考虑到很多漏洞。考虑因素的矩阵不仅仅是隐藏一些类以避免示例化的愿望。
由于类是抽象的,所以除了作为祖先之外,不能直接使用它,所以你已经有了一些保护。如果你想在你的模块之外阻止使用祖先,让它的构造函数privateinternal,这将解决这个问题:

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

现在,您已经保护了直接示例化(abstract)或用作基类(通过使用abstract和私有构造函数),所以最后要做的事情是给予一个像AbstractBaseRepository这样的好名字,人们将按照惯例不去管它。
如果你想讨论 “为什么” 这是设计决定,或技术限制,或保护规则.然后尝试discussion forumsYouTrack中的功能或语言更改建议。但要注意,事情并不像最初看起来那么简单。这些规则的存在是有原因的(* 即使其他语言危险地允许 *)。

mm5n2pyu

mm5n2pyu2#

只将其设为抽象类

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

eanckbw93#

A comment from Roman Elizarov向我暗示,这个限制很大程度上是因为internal类的作者可能没有设计public类的想法,因此可能会意外地暴露一些东西。
他还指出,这种限制有一些缺点,他链接到his feature request以允许这种 * 如果 * internal类用@PublishedApi注解。这对我来说似乎是一个很好的妥协,但我没有得到的印象是,该功能将很快到来。

相关问题