我有以下类层次结构:
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'应该相同或更少 允许比其超类有效可见性'私人'
我不想在其他任何地方使用BasicRepositoryImpl
,因此声明为private
,我想在其他文件中使用LocalRepository
和RemoteRepository
:< / p>
class Presenter(val repo: Repository)
val p = Presenter(LocalRepository())
但是这个错误阻止我创建这样的层次结构。为什么?怎么了?
答案 0 :(得分:11)
该类及其祖先必须可以从using类中访问所有。否则在加载祖先类时会违反,而不仅仅是调用其方法或使用其功能。在存在可访问性的所有情况下,Kotlin都非常清楚和清楚。
稍微打开它会允许以后可能导致真正的JVM访问冲突的事情,比如公共类中的inline
函数,内联到另一个类,调用私有不可访问的某些东西祖先。如果您觉得可以像这样做一个混合的可访问性模型,那么您就不会考虑许多漏洞。考虑因素的范围大于仅隐藏实例化的某些类的愿望。
由于类是抽象的,除了作为祖先之外,它不能直接使用,所以你已经有了一些保护。如果要阻止在模块之外用作祖先,请创建其构造函数private
或internal
,这将解决该问题:
abstract class BasicRepositoryImpl private constructor() { ... }
现在你已经保护了直接实例化(abstract
)或者用作基类(通过使用abstract
和私有构造函数),所以最后要做的就是给它一个好名字,比如{{1按惯例,人们将不管它。
如果你想讨论&#34;为什么&#34; 这是设计决定,技术限制或保护规则......那么试试discussion forums,一个功能或YouTrack中的语言更改建议。但要注意事情并不像他们最初看起来那么简单。这些规则是有原因的(即使其他语言危险地允许)。
答案 1 :(得分:0)
只能使它成为抽象类
定义: 抽象类是一个声明为abstract的类 - 它可能包含也可能不包含抽象方法。抽象类不能被实例化,但它们可以被子类化。