Edited at

Java開発者に送るKotlinのClass

Java開発者の方に向けて、Kotlinのクラスについて書きます。


クラスの定義

classキーワードに続いて、クラス名を記述します。

Dogクラスを定義してみます。

class Dog {

}

クラスの継承やインターフェースの実装はコロンに続けて記述します。

先ほどのDogクラス、Animalクラスを継承させてみます。

class Dog: Animal() {

}

さらに、Walkableインターフェースを実装してみましょう。

class Dog: Animal(), Walkable {

}


プロパティ

Kotlinのクラスはプロパティを持つことができます。

これはJavaのフィールド、ゲッター、セッターを合わせたものです。

DogクラスにnameというString型のプロパティを宣言してみましょう。

varキーワードを使います。

class Dog {

var name: String = "pochi"
}

val dog = Dog()
val aName = dog.name // ゲッターとして動作
dog.name = "taro" // セッターとして動作

読み取り専用にしたければ、valキーワードを使いましょう。

class Dog {

val name: String = "pochi"
}

val dog = Dog()
val aName = dog.name // ゲッターとして動作
dog.name = "taro" // コンパイルエラー!

valキーワードは再代入不可のため、クラス内部からも値を変更できません。

クラス内で変更可能とする場合はprivate setキーワードを使います。

class Dog {

var name: String = "pochi"
private set

fun updateName(newName: String) {
this.name = newName
}
}

val dog = Dog()
dog.updateName("taro")

ここで、「いやいや、JavaでフィールドをPublicにしたのと一緒でしょ?」と思った方は鋭いです。

Kotlinのプロパティはゲッター、セッターそしてフィールドが明確に分かれています。

詳しくはこちら


プライマリコンストラクタ

Kotlinのコンストラクタは少し変わった位置に書きます。

class Dog constructor(/* ここがコンストラクタ */) {

}

constructorキーワードは省略できます。アノテーションを付加する場合などは省略できません。

この位置に書くコンストラクタをプライマリコンストラクタと呼びます。

コンストラクタと言っても、記述できるのはプロパティとコンストラクタの引数リストです。


コンストラクタでプロパティ定義する

コンストラクタ引数にvarvalキーワードをつけると、そのままプロパティになります。

class Dog(var name: String) {

}

↑は↓と同義です。

class Dog(name: String) {

var name: String = name
}


イニシャライザ

プライマリコンストラクタは、コンストラクタ引数とプロパティの宣言が出来ました。その他、クラスの初期化時に行う処理はイニシャライザに記述できます。

class Point(val x: Int, val y: Int)

class Size(val width: Int, val height: Int)

class Regtangle(val origin: Point, val size: Size) {
val area: Int

init {
this.area = this.size.width * this.size.height
}
}

val rectangle = Regtangle(30, 10, 10, 20)
println(rectangle.area)

クラスRegtangleはコントラクタに原点と大きさを受け、イニシャライザで面積を計算しています。


セカンダリコンストラクタ

プライマリコンストラクタがあるのでセカンダリコンストラクタもあります。

セカンダリコンストラクタは複数定義することができます。

セカンダリコンストラクタは:に続けてプライマリコンストラクタを呼び出す必要があります。

class Point(val x: Int, val y: Int)

class Size(val width: Int, val height: Int)

class Regtangle(val origin: Point, val size: Size) {

constructor(x: Int, y: Int, width: Int, height: Int): this(Point(x, y), Size(width, height))

}

クラスRegtangleに原点とサイズを個別のパラメータで受け取るコンストラクタを追加しました。


JavaとKotlinを見比べてみる

JavaでDogクラスを定義します。

nameとageというフィールドがあり、それぞれゲッターとセッターが定義されています。

public class Dog {

private String name;
private int age;

public Dog(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

}

これをKotlinで書くと?

class Dog(var name: String, var age: Int)

これだけで済んでしまいます。