我有一个如下的类层次结构:
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
,我想在其他文件中使用LocalRepository
和RemoteRepository
,如下所示:
class Presenter(val repo: Repository)
val p = Presenter(LocalRepository())
但这个错误阻止了我创建这样一个层次结构。为什么?有什么问题吗?
3条答案
按热度按时间s6fujrry1#
类及其祖先必须all可从using类访问。否则,在加载祖先类时,而不仅仅是调用它的方法或使用它的功能时,这将是一个违规行为。Kotlin在所有存在可访问性的情况下都非常干净和清晰。
稍微打开它会允许一些可能导致真实的JVM访问冲突的东西,比如公共类中的
inline
函数,内联到另一个类中,调用祖先的私有不可访问 something。如果你觉得做一个像这样的可访问性的混合模型是可以的,那么你没有考虑到很多漏洞。考虑因素的矩阵不仅仅是隐藏一些类以避免示例化的愿望。由于类是抽象的,所以除了作为祖先之外,不能直接使用它,所以你已经有了一些保护。如果你想在你的模块之外阻止使用祖先,让它的构造函数
private
或internal
,这将解决这个问题:现在,您已经保护了直接示例化(
abstract
)或用作基类(通过使用abstract
和私有构造函数),所以最后要做的事情是给予一个像AbstractBaseRepository
这样的好名字,人们将按照惯例不去管它。如果你想讨论 “为什么” 这是设计决定,或技术限制,或保护规则.然后尝试discussion forums,YouTrack中的功能或语言更改建议。但要注意,事情并不像最初看起来那么简单。这些规则的存在是有原因的(* 即使其他语言危险地允许 *)。
mm5n2pyu2#
只将其设为抽象类
eanckbw93#
A comment from Roman Elizarov向我暗示,这个限制很大程度上是因为
internal
类的作者可能没有设计public
类的想法,因此可能会意外地暴露一些东西。他还指出,这种限制有一些缺点,他链接到his feature request以允许这种 * 如果 *
internal
类用@PublishedApi
注解。这对我来说似乎是一个很好的妥协,但我没有得到的印象是,该功能将很快到来。