【问题标题】:This type has a constructor and must be initialized here - Kotlin这种类型有一个构造函数,必须在这里初始化 - Kotlin
【发布时间】:2016-03-18 20:08:27
【问题描述】:

我刚刚开始使用 Kotlin 试验 Android 应用程序。我只是想像这样继承Application 类:

class SomeApp : Application {

}

但是编译器会发出警告:

建议将其更改为:

class SomeApp : Application() {
    override fun onCreate() {
        super.onCreate()
    }
}

我读到了primary and secondary constructors in the docs。那么如果超类有主构造函数,那么这里有必要写吗?像Application类有自己的构造函数

public Application() {
    super(null);
}

那么派生需要主构造函数吗?或者我不能做类似 Java 的事情吗:

class SomeApp : Application {
   constructor SomeApp(){
      super();
    }
}

或者这个错误暗示了别的什么?谁能详细解释我?我对这门语言很陌生,这对我来说很奇怪。

编辑:在 java 中我可以执行以下操作:class SomeApp extends Application{ }

它有隐式构造函数,所以我不必写:class SomeApp extends Application{ public Application(){ super(); } } 但是在 kotlin 中我必须定义如下的空构造函数: class SomeApp:Application(){ } ?

【问题讨论】:

    标签: android constructor kotlin kotlin-android-extensions


    【解决方案1】:

    这与主要/次要构造函数无关。

    在 JVM(以及几乎其他任何地方)上,当您创建 SomeApp 的实例时,会调用基类 Application 的构造函数

    在 Java 中,语法就像你说的:

    class SomeApp : Application {
        constructor SomeApp(){
          super();
        }
    }
    

    在这里你必须声明一个constructor,然后你必须调用超类的构造函数。

    在 Kotlin 中,概念完全相同相同,但语法更好:

    class SomeApp() : Application() {
        ...
    }
    

    在这里,您声明了一个不带参数的构造函数SomeApp(),并说它调用Application(),在这种情况下不带参数。这里Application()与java sn-p中super()的效果完全一样。

    在某些情况下可能会省略一些括号:

    class SomeApp : Application()
    

    错误文本显示:This type has a constructor, and thus must be initialized here。这意味着Application 类型是一个类,而不是一个接口。接口没有构造函数,因此它们的语法不包括构造函数调用(括号):class A : CharSequence {...}。但是Application 是一个类,所以你调用一个构造函数(任何一个,如果有的话),或者“在这里初始化它”。

    【讨论】:

    • 什么意思?这就是它的全部内容
    • @KrupalShah 我编辑了答案。是你问的吗?
    • 所以据我了解,没有隐式的空构造函数。我说的对吗?
    • @KrupalShah 如果没有指定其他内容,则存在隐式空构造函数,但您必须显式调用它
    • 这很简单:不像构造函数声明,构造函数invocation是一个动作,它可能有副作用。没有副作用可能是隐含的,这就是 Kotlin 背后的哲学
    【解决方案2】:

    你不需要

    class SomeApp : Application() {
       constructor SomeApp(){
          super();
        }
    }
    

    因为这是等价的。如果类有主构造函数,则可以(并且必须)使用主构造函数的参数在此处初始化基类型。

    class SomeApp : Application() {
    }
    

    在java中也等价于

    class SomeApp extends Application {
         public SomeApp(){
           super();
         }
    }
    

    【讨论】:

    • 嘿,我说的是 Kotlin。你在说什么?
    • 我认为您将他的“覆盖 onCreate”与声明构造函数混淆
    • 那我不知道他在问什么。自动完成在 override onCreate 中添加的原因是因为它看到他的构造函数中有错误,并决定过度急切地添加 onCreate 覆盖。
    • 正确,onCreate 无关。
    猜你喜欢
    • 2017-10-29
    • 1970-01-01
    • 2019-12-24
    • 2014-07-02
    • 2020-09-15
    • 1970-01-01
    • 2019-10-07
    • 2020-09-26
    • 2015-09-11
    相关资源
    最近更新 更多