为什么公开课不能扩展私人课? [英] Why public class can't extend private class?

查看:61
本文介绍了为什么公开课不能扩展私人课?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下类层次结构:

I have a following class hierarchy:

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

但是出现以下错误:

子类有效可见性公共"应该相同或更少 比其超类有效可见性私人"更宽容

Subclass effective visibility 'public' should be the same or less permissive than its superclass effective visibility 'private'

我不想在其他任何地方使用BasicRepositoryImpl,因此将其声明为private,并且我想在其他文件中使用LocalRepositoryRemoteRepository,例如:

I don't want to use BasicRepositoryImpl anywhere else, so it's declared private, and I want to use LocalRepository and RemoteRepository in other files like this:

class Presenter(val repo: Repository)

val p = Presenter(LocalRepository())

但是该错误使我无法创建这样的层次结构.为什么?怎么了?

But that error prevents me to create such a hierarchy. Why? What's wrong with it?

推荐答案

该类及其祖先必须全部可以从using类中访问.否则,在加载祖先类时,不仅会调用其方法或使用其功能,这将是违法的.在存在可访问性的所有情况下,Kotlin对此都非常干净和明确.

The class and its ancestors must all be accessible from the using class. Otherwise it would be an violation when loading the ancestor class, not just calling its methods or using its functionality. Kotlin is very clean and clear about this in all cases where accessibility is present.

稍微打开它可以使以后可能引起真正的JVM访问冲突的事情发生,例如公共类中的inline函数,内联到另一个类中,调用私有的不可访问的 something 祖先.如果您觉得可以做这样的混合可访问性模型,可以考虑的地方很多.考虑的矩阵大于仅希望隐藏某些类以免于实例化的需求.

Opening it up a little would allow things that could cause real JVM access violations later, like an inline function in the public class, inlined into another class, calling the private non accessible something of the ancestor. There are many holes you aren't considering if you feel it is ok to do a mixed model of accessibility like this. The matrix of considerations is larger than only the desire to hide some classes from instantiation.

由于类是抽象的,因此只能作为祖先使用,不能直接使用,因此您已经有了一些保护.如果要阻止在模块之外用作祖先,请将其构造函数设置为privateinternal,这将解决该问题:

With the class being abstract, it cannot be used directly other than as an ancestor, so you have some protection already. If you want to block use as an ancestor outside of your module, make its constructor private or internal and that will solve that problem:

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

现在您已经保护了直接实例化(abstract)或用作基类(通过使用abstract和私有构造函数),所以最后要做的就是给它起一个好名,例如AbstractBaseRepository,人们会习惯不要管它.

Now you have protected direct instantiation (abstract) or use as a base class (by using abstract and private constructors) so the last things to do is give it a good name like AbstractBaseRepository and people will by convention leave it alone.

如果您要讨论为什么" ,这是设计决定,技术限制或保护性规则……然后尝试 YouTrack 中的功能或语言更改建议.但是要当心,事情并不像看起来那样简单.这些规则之所以存在是出于原因(即使其他语言危险地允许).

If you want to discuss "why" this is the design decision, or technical limitation, or protective rule ... then try the discussion forums, a feature or language change suggestion in YouTrack. But beware things are not as simple as they first appear to be. These rules are there for reasons (even if other languages dangerously allow).

这篇关于为什么公开课不能扩展私人课?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆