基底クラスがコンストラクタを持つ場合、それを明示的に呼び出す必要がkotlinではあります。
kotlinではクラスと継承の定義にコンストラクタ定義まで含めることができます。
This type has a constructor and must be initialized here - Kotlin
// Java
public class RealmString extends RealmObject implements Serializable {
private String value;
}
// Bad
class RealmString : RealmObject, Serializable {
var value: String
}
// Good
class RealmString() : RealmObject(), Serializable {
// RealmStringクラスはRealmObjectクラスを継承し、Serializableインターフェースの実装を持ちます。
// RealmStringクラスは実体化されると、基底クラスのコンストラクタを引数で呼び出します。
var value: String
}
クラス変数として定義される変数は、初期値が必要になります。
初期値が未定の場合はlateinit
修飾子を使うこともできます。
lateinit
で変数を定義した場合、必要な初期化をスキップすることができ、
値が割り当てられるまでプロパティアクセスを失敗させます。
// Java
private String value;
// Bad
var value: String
// Good
var value: String? = null
lateinit var value: String
これはTypeAdapterのコンストラクタに関数リテラルを渡していると解釈されるために起きる。
object
キーワードを使う事で、匿名サブクラスのインスタンスを返す事ができる。
// Bad
var foo = Foo() {
...
}
// Good
var foo = object: Foo() {
...
}
TypeAdapter<RealmString> adapter = new TypeAdapter<>() {
@Override
public RealmString read(JsonReader reader) throws IOException {
return null;
}
@Override
public void write(JsonWriter writer, RealmString value) throws IOException {
}
};
// Bad
var adapter: TypeAdapter<RealmString> = TypeAdapter<RealmString>() {
override fun read(reader: JsonReader) : RealmString? {
return null
}
override fun write(writer: JsonWriter, value: RealmString) {
}
}
// Good
var adapter: TypeAdapter<RealmString> = object: TypeAdapter<RealmString>() {
override fun read(reader: JsonReader) : RealmString? {
return null
}
override fun write(writer: JsonWriter, value: RealmString) {
}
}