Kotlin / Programming

ザクっと理解するKotlin Class

Kotlinにおけるクラスについて、公式ドキュメントをもとにわかりやすく解説します。

コード例を交えながら、初心者でも理解しやすいように説明しています。

Kotlinでのクラスの基本を理解して、オブジェクト指向プログラミングの基礎を身につけましょう。

この記事はKotlin公式サイトを翻訳しながらわかりやすくまとめています。

クラス

kotlinではclassキーワードを使うことでクラスを宣言できます。

クラスを宣言するときに、クラス名やコンストラクタなどを含んだクラスヘッダーと波括弧で囲まれたクラスボディーを書くことができます。

class Person { /* ... */ }
Kotlin

これらは任意のためクラスにボディーがない場合は波括弧は省略できます。

// 波括弧内に何もないなら省略できる
class Person
Kotlin

コンストラクタ

クラスには1つのプライマリコンストラクタと1つ以上のセカンダリコンストラクタを指定できます。

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

プライマリコンストラクタはクラスのヘッダーの一部で、クラス名と任意の型パラメータの後に続きます。

class Person constructor (name: String) { /* ... */ }
Kotlin

プライマリコンストラクタがアノテーションなし、可視性修飾子(publicとかprivateとか)なしの場合、constructorキーワードを省略することができます。

class Person(name: String) { /* ... */ }

// アノテーションも可視性修飾子もあるため省略不可
class Person public @Inject constructor(name: String) { /* ... */ }
Kotlin

プライマリコンストラクタにはコードを記述できません。初期化用のコードはinitキーワードがついたブロックで行います。

インスタンスの初期化中、初期化ブロックは、ボディーに書かれている順序で実行されます。

下記の場合はプロパティとinit内部が交互に実行されます。

プライマリコンストラクタ内でプロパティを宣言し初期値を設定することができます。宣言時の最後のカンマは任意です。

これによりJavaのように内部で変数を宣言する必要がなく、valで宣言した場合は不変性が確保できます。

// これはJavaで同じ処理をした時のコードです
public static void main(String[] args) {
  Person person = new Person("Taro");
  person.printName();
}

// Javaでクラス内で変数宣言をする場合
public class Person {
  private String name;

  public Person(String name) {
      this.name = name;
  }

  public void printName() {
      System.out.println(name);
  }
}
Java

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

セカンダリコンストラクタはconstructorキーワードで設定できます。

プライマリコンストラクタを設定したうえでセカンダリコンストラクタを設定する場合は、直接的もしくは他セカンダリコンストラクタを使用して間接的にプライマリコンストラクタの値を設定する必要があります。

初期化ブロック内のコードは、プライマリコンストラクタの一部になります。

セカンダリコンストラクタの最初の文にアクセスした時点で、プライマリコンストラクタへ値を渡します。

そのため、すべての初期化ブロックとプロパティの初期化コードは、セカンダリコンストラクタの本体が実行される前に実行されます。

これはクラスがプライマリコンストラクタを設定していなくても行われるため、初期化ブロックの方が先に実行されます。

fun main() {
    Person("Kato")
}

class Person {
    // 処理順2
    constructor(count: String) {
        println("コンストラクタ: $count")
    }
    
    // 処理順1
    init {
        println("初期化ブロック: 1")
    }
}

// 出力結果
// 初期化ブロック: 1
// コンストラクタ: Kato
Kotlin

抽象クラスではなくプライマリとセカンダリ両方のコンストラクタがない場合、自動的に引数なし、可視性publicのプライマリコンストラクタが生成されます。

クラスにpublicのコンストラクタを設定したくない場合は設定したい可視性とともに空のプライマリコンストラクタを設定してください。

class NoConstructor private constructor() { /* ... */ }
Kotlin

クラスのインスタンス化

インスタンスを作成するには普通の関数を呼び出すようにコンストラクタを呼びます。(kotlinにnewキーワードはありません)

fun main() {
    Person()
}

class Person { /* ... */ }
Kotlin

抽象クラス

abstractキーワードをつけて、プロパティや関数と一緒にクラスを宣言できます。

抽象メンバーは実装部分を持ちません。また抽象クラスやメソッドにopenアノテーションは不要です。

fun main() {
    val john = Person("John")
    john.greet() // Hi, I'm John
    john.walk() // I'm walking
}

class Person(val name: String): Animal() {
    fun greet() = println("Hi, I'm $name")
    override fun walk() = println("I'm walking")
}

abstract class Animal() {
    abstract fun walk()
}
Kotlin

また、抽象クラスではなくてopenキーワードがついている関数は抽象関数で上書きできます。

コンパニオンオブジェクト

クラスのインスタンスを持たないが、ファクトリーメソッドのようにクラス内の変数や関数にアクセスする必要がある関数をかきたい場合、クラス内にオブジェクト宣言のメンバーとして関数を書くことができます。

詳しくは別記事に書く予定です。

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です