Kotlin不要叫超级

时间:2018-06-26 14:28:12

标签: android inheritance kotlin

我有一个扩展另一个的类,但是在这个类中,我不想调用超级构造函数。 我该怎么解决?

这是我的代码的摘录

class SubarticlePagerAdapter(fragmentManager: FragmentManager, context: Context, var selectedArticleName: String) : ArticlePagerAdapter(fragmentManager, context) {

    var subarticleDao: ArticleDao
    var itemCount = 0

    init {
        ApplicationHelper().getApplication(context).appComponent.inject(this)
        subarticleDao = ApplicationHelper().getApplication(context).subarticleDaoSession.articleDao
        initBundles(context)
    }

    override fun initBundles(context: Context?) {
        }
    }

我的问题是,当调用此构造函数时,将首先运行父类构造函数,然后从那里调用initBundles(),但那时未设置subarticleDao和selectedArticleName,并且出现异常。

1 个答案:

答案 0 :(得分:2)

TL; DR

我建议您将代码从init块移至initBundles函数,并在初始化后在其中使用变量。这样就无需避免调用超类构造函数。

广泛答案

我认为您应该考虑要对设计进行的处理。解决语言的习语通常不是一个好主意,也不是一个好的设计的标志-至少当Kotlin是您的语言时:)

您对代码所做的操作(从您的超类中覆盖了一种可能抽象的方法initBundles几乎是template method pattern。因此,在我看来initBundles的目的是允许子类自定义初始化的部分...基本上,您在init块中所做的工作。

EDIT :正如Paul在注释中指出的那样,您不能在基础类初始化完成之前使用成员selectedArticleName。因此,如果基类在初始化期间调用initBundles,则子类中的属性将不会被初始化,如Paul's link所述。

由于您在代码段中不使用selectedArticleName,因此可以将初始化内容移至initBundles函数,然后在其中初始化subarticleDao

但是,如果此时需要使用子类属性,我真的建议您重新考虑设计。应该有几种方法可以解决此问题,但是要确定最适合您的要求的方法,则需要进一步了解您的设计意图。