Kotlin Advent Calendar 2012 (全部俺)

JavaプログラマのためのKotlin入門

11日目:クラスと共に暮らす

f:id:ngsw_taro:20071123141531j:plain

いきなりしょうもないダジャレですみませんw 今日からオブジェクト指向に関する機能について紹介していきます。今日はクラスについてお話しします。

クラスとコンストラクタ

では早速Kotlinでクラスを定義してみます。次のコードはメンバをまったく持たないクラス MyFirstClassを定義しています。

class MyFirstClass()

Javaと同じようにキーワード class によってクラスは定義されます。クラス名の後の括弧はコンストラクタです。そして、クラス本体に何も記述する内容がない場合は波括弧を省略できます。このクラスのインスタンスを生成してみましょう。

val instance = MyFirstClass()
println(instance.javaClass) // class MyFirstClass

キーワード new が見当たりませんが、これで正しいのです。コンストラクタの呼び出しはインスタンス生成の場面でしか登場しないので、new は冗長であると設計者が判断したためでしょう。ちなみに javaClass は、すべてのオブジェクトが持つプロパティで、java.lang.Classを表します。

コンストラクタ

クラス名の直後の括弧がコンストラクタに当たります。このコンストラクタのことを、プライマリ・コンストラクタと言います。プライマリ・コンストラクタでは、主にプロパティに値を設定してインスタンスを初期化します。次のコードは、プロパティ name を持ったクラス Student の例です。

class Student(val name : String)

やはり波括弧の対を置いてブロックを形成する必要はありません。name に付いているキーワード val は必要に応じて var とすることも可能です。このクラスの使用例を次に示します。

fun main(args : Array<String>) {
  val taro = Student("Taro")
  println("My name is ${taro.name}.") // My name is Taro.
}

name に val も var も付けなかった場合、変更不可な変数でかつ、そのスコープはそのクラスの匿名イニシャライザのみです。

匿名イニシャライザ

プライマリ・コンストラクタから直接プロパティの値をセットするのは便利ですが、なんらかの処理を施した後にプロパティを初期化したい場合もあります。そこで使用する機能が匿名イニシャライザです。コンストラクタのようにインスタンスの初期化を行うために使用しますが、匿名イニシャライザが呼び出されてインスタンスを生成する、ということはあり得ません。インスタンス生成の唯一の入口はプライマリ・コンストラクタなのです。

例を交えて匿名イニシャライザの書き方を紹介します。先に登場したクラス Student に匿名イニシャライザを導入しましょう。name は生徒(Student)の氏名を表すため、nullや空文字列が渡されないようにしたいところです。言語機能上、この場合はnullを渡すことはできないので*1、空文字列が渡された場合は例外を投げて初期化を中止します。次のようなコードになります*2

class Student(name : String) {
  
  public val name : String
  {
    if(name.length == 0) throw IllegalArgumentException()
    this.name = name
  }
}
 
fun main(args : Array<String>) {
  val taro = Student("Taro")
  println("My name is ${taro.name}.") // My name is Taro.
  
  Student("") // throw EXCEPTION!!!
}

この様に、波括弧の対で匿名イニシャライザを定義します。

インスタンス関数

クラス内に関数を定義することができます。それはインスタンス関数として、クラスのインスタンスに対して呼び出します。

class Square(val size : Double) {
  fun calcArea() = size * size
}
 
fun main(args : Array<String>) {
  val s = Square(4.0)
  println(s.calcArea()) // 16.0
}

まとめと次回予告

今日はオブジェクト指向の要であるクラスの基本を学びました。クラスはプライマリ・コンストラクタと共に定義します。プライマリ・コンストラクタインスタンスを初期化するためのパラメータを受け取ります。たいていはそのままプロパティとして保持しますが、なんらかの処理が必要な場合は匿名イニシャライザを使用します。また、インスタンス関数としてクラス内部に関数を記述することができます。

今夜、JetBrains勉強会でKotlinの紹介ということで登壇させていただきます。明日は小休止ということで、その発表内や勉強会の感想などを書きます。

日記

勉強会でKotlin布教がんばる。Kotlin、盛り上がって欲しい。

*1:この機能については後日説明します。

*2:Kotlinにはこのような検査を行う便利な関数が標準ライブラリにありますので、通常はこのような記述はしないでしょう。