【Kotlin】レッスン5-11:インターフェースの定義と使い方を理解しよう

ながみえ

一つ前のページでは抽象クラスについて学習しました。

今回は インターフェース について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:関数編
Lesson4:コレクション編
Lesson5:オブジェクト指向編

 ・Lesson5-1:クラスの基本を理解しよう
 ・Lesson5-2:プライマリコンストラクタを理解しよう
 ・Lesson5-3:セカンダリコンストラクタを理解しよう
 ・Lesson5-4:ふたつのコンストラクタを使いこなそう
 ・Lesson5-5:アクセス修飾子とカプセル化を理解しよう
 ・Lesson5-6:静的メンバとインスタンスメンバを理解しよう
 ・Lesson5-7:クラスの継承を理解しよう
 ・Lesson5-8:メソッドのオーバーライドを理解しよう
 ・Lesson5-9:クラスを拡張しよう
 ・Lesson5-10:抽象クラスを理解しよう
 ・Lesson5-11:インターフェースを理解しよう ◁今回はココ
 ・Lesson5-12:データクラスを理解しよう
 ・確認問題5-☆1:モンスター捕獲ゲームを作ろう
 ・確認問題5-☆2:マルバツゲームを作ろう
 ・確認問題5-☆3:石取りゲームを作ろう

<<前のページ

学習記事一覧

次のページ>>

インターフェース入門|定義・使い方・活用メリットを解説

オブジェクト指向の重要な概念として「インターフェース」があります。

インターフェースはクラスが持つべき共通の機能や特性を定義する仕組みです。

本記事では、インターフェースの基本から具体的な使用例、さらに抽象クラスとの違いについて解説します。

インターフェースの役割と基本構文

インターフェースとは、複数のクラスに共通するプロパティやメソッドを定義するための設計図のようなものです。

これにより異なるクラスに一貫性のある機能を持たせることができます。

インターフェース自体はインスタンス化できず、具体的な処理はインターフェースを実装するクラスに任されます。

例えるなら、インターフェースは「契約書」で、実装するクラスがその契約内容を実行に移す役割を果たします。

インターフェースは interfaceキーワード を使用して定義します。

インターフェースの中には抽象プロパティや抽象メソッドを定義できます。

interface インターフェース名 {	// インターフェースの定義
    val 抽象定数名: 型		  // 抽象プロパティ
    fun 抽象メソッド名()		 // 抽象メソッド
}

抽象プロパティや抽象メソッドが何か分からない方は、先に Lesson5-10:抽象クラスを理解しよう の記事を確認してください。

インターフェースを用いたコード例

以下は上記のコードを使用した具体例です。

// インターフェースの定義
interface Animal {		// Animalインターフェースの定義
    val name: String	// 抽象プロパティ
    fun makeSound()		// 抽象メソッド
    fun sleep() {		// 通常のメソッドも定義可能
        println("$name is sleeping")
    }
}

// インターフェースの実装
class Dog(override val name: String) : Animal {	// Animalインターフェースを実装したDogクラスの定義
    override fun makeSound() {					// 抽象メソッドをオーバーライド
        println("$name says Woof!")
    }
}
class Cat(override val name: String) : Animal {	// Animalインターフェースを実装したCatクラスの定義
    override fun makeSound() {					// 抽象メソッドをオーバーライド
        println("$name says Meow!")
    }
}

fun main() {
    val dog = Dog("Buddy")	// Dogクラスのインスタンス生成
    val cat = Cat("Kitty")	// Catクラスのインスタンス生成
    dog.makeSound()			// Buddy says Woof!
    cat.makeSound()			// Kitty says Meow!
    dog.sleep()				// Buddy is sleeping
    cat.sleep()				// Kitty is sleeping
}
  • DogCatのインスタンスを作成し、それぞれがAnimalインターフェースを実装していることを確認します。
  • 抽象メソッドmakeSoundは具体的な実装を持ち、クラスごとに異なる動作をします。
  • インターフェースに具体的なメソッドsleepを定義することで、全ての実装クラスで共通の処理を記述できます。

インターフェースと抽象クラスとの違い

インターフェースと抽象クラスには似た部分がありますが、それぞれ異なる用途があります。

以下に主な違いを挙げます。

観点インターフェース (interface)抽象クラス (abstract class)
継承の制限1つのクラスが複数のインターフェースを実装可能1つの子クラスには1つの親クラスのみ
コンストラクタの定義できない定義できる
状態(プロパティ)の保持値は持てない(val/var定義は可能、状態は不可)プロパティに値を持たせられる
メソッドの実装抽象/通常どちらも可抽象/通常どちらも可
抽象プロパティの宣言
主な用途機能の契約(共通API定義)基本クラスの設計と共通処理の提供
インスタンス化不可不可
継承キーワード: インターフェース名: 親クラス名()
実装クラスでのoverride必須?すべての抽象メンバをoverrideする必要あり抽象メンバのみoverrideが必須(通常メソッドは任意)

インターフェースは「共通の機能だけを複数のクラスに横断して実装」するのに対し、抽象クラスは「共通の状態と処理を持たせたいとき、1つの共通ベースクラスとして設計」できます。

まとめ|インターフェースで柔軟な設計を実現しよう

インターフェースは、異なるクラスに共通の機能や約束ごと(契約)を持たせたいときに役立つ仕組みです。

クラス間の共通点をまとめたり、将来の拡張や機能追加にも柔軟に対応できるのが大きな特徴です。

インターフェースの特性を理解して、場面に応じて効果的に活用していきましょう。

練習問題|インターフェースを使って動物園管理システムを作成しよう

インターフェースを利用して動物園の動物を管理するシステムを作成しましょう。

物の鳴き声や情報をインターフェースを用いて統一的に扱い、動物を動的に管理する仕組みを学びます。

この問題の要件

以下の要件に従ってコードを完成させてください。

  1. Animal インターフェースを定義し、以下を実装すること:
    • 鳴き声を出力する makeSound メソッド。
    • 動物の名前と年齢を表示する displayInfo メソッド。
  2. Lion クラスを作成し、Animal インターフェースを実装すること:
    • 名前と年齢を保持するプロパティ name と age を定義。
    • makeSound メソッドで「[名前] が吠えました: ガオー!」を表示。
    • displayInfo メソッドで「ライオン – 名前: [名前], 年齢: [年齢] 歳」を表示。
  3. Elephant クラスを作成し、Animal インターフェースを実装すること:
    • 名前と年齢を保持するプロパティ name と age を定義。
    • makeSound メソッドで「[名前] が鳴きました: パオーン!」を表示。
    • displayInfo メソッドで「ゾウ – 名前: [名前], 年齢: [年齢] 歳」を表示。
  4. Zoo クラスを作成し、以下を実装すること:
    • Animal 型のオブジェクトを格納する animals リストを定義。
    • Animal をリストに追加する addAnimal メソッドを作成。
      動物をリストに追加した後「動物が追加されました。」と表示し、追加された動物の情報を displayInfo メソッドで表示。
    • リスト内の全ての動物の情報を表示する displayAllAnimals メソッドを作成。
  5. メイン関数を作成し、以下を実施すること:
    • Zoo クラスのインスタンスを作成。
    • Lion クラスと Elephant クラスのインスタンスを作成。
    • Zoo インスタンスに動物を追加。
    • Zoo 内の全ての動物情報を表示。
    • 各動物の鳴き声を表示。

ただし、以下のような実行結果となること。

動物が追加されました。
ライオン - 名前: レオ, 年齢: 5 歳
動物が追加されました。
ゾウ - 名前: エリー, 年齢: 10 歳
すべての動物の情報:
ライオン - 名前: レオ, 年齢: 5 歳
ゾウ - 名前: エリー, 年齢: 10 歳
レオ が吠えました: ガオー!
エリー が鳴きました: パオーン!

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1:Animalインターフェースの定義
  □ makeSound関数の定義
  □ displayInfo関数の定義
2:Lionクラスの定義
  □ プライマリコンストラクタでnameとageプロパティを定義
  □ Animalインターフェースを実装
  □ makeSound関数をオーバーライドし、名前と鳴き声を出力
  □ displayInfo関数をオーバーライドし、ライオンの情報を出力
3:Elephantクラスの定義
  □ プライマリコンストラクタでnameとageプロパティを定義
  □ Animalインターフェースを実装
  □ makeSound関数をオーバーライドし、名前と鳴き声を出力
  □ displayInfo関数をオーバーライドし、ゾウの情報を出力
4:Zooクラスの定義
  □ MutableList型のanimalsプロパティを初期化
  □ addAnimal関数の定義
  □ □ リストに動物を追加
  □ □ 「動物が追加されました。」と出力
  □ □ 追加された動物の情報を表示
  □ displayAllAnimals関数の定義
  □ □ 「すべての動物の情報:」と出力
  □ □ for文で全ての動物の情報を表示
5:main関数の定義
  □ Zooクラスのインスタンスを作成
  □ Lionクラスのインスタンスを作成
  □ Elephantクラスのインスタンスを作成
  □ addAnimal関数を用いてライオンとゾウを動物リストに追加
  □ displayAllAnimals関数を用いて全ての動物情報を表示
  □ makeSound関数を用いて各動物の鳴き声を出力

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

// インターフェース Animal を定義
interface Animal {
    // 動物の鳴き声を出すメソッド
    fun makeSound()
    // 動物の情報を表示するメソッド
    fun displayInfo()
}

// Animal インターフェースを実装する Lion クラスを定義
class Lion(val name: String, val age: Int) : Animal {
    // makeSound メソッドの実装
    /*【穴埋め問題1】
    ここに makeSound メソッドをオーバーライドし、ライオンの鳴き声を出すコードを書いてください。
    */

    // displayInfo メソッドの実装
    /*【穴埋め問題2】
    ここに displayInfo メソッドをオーバーライドし、ライオンの名前と年齢を表示するコードを書いてください。
    */
}

// Animal インターフェースを実装する Elephant クラスを定義
class Elephant(val name: String, val age: Int) : Animal {
    // makeSound メソッドの実装
    /*【穴埋め問題3】
    ここに makeSound メソッドをオーバーライドし、ゾウの鳴き声を出すコードを書いてください。
    */

    // displayInfo メソッドの実装
    /*【穴埋め問題4】
    ここに displayInfo メソッドをオーバーライドし、ゾウの名前と年齢を表示するコードを書いてください。
    */
}

// Animal を管理する Zoo クラスを定義
class Zoo {
    // 動物リストを保持するプロパティ
    private val animals: MutableList<Animal> = mutableListOf()

    // 動物を追加するメソッド
    fun addAnimal(animal: Animal) {
        animals.add(animal)
        // 動物が追加されたメッセージとその情報を表示
        println("動物が追加されました。")
        /*【穴埋め問題5】
        ここに追加された動物の情報を表示するコードを書いてください。
        */
    }

    // すべての動物情報を表示するメソッド
    fun displayAllAnimals() {
        println("すべての動物の情報:")
        /*【穴埋め問題6】
        ここに for 文を使って、すべての動物の情報を表示するコードを書いてください。
        */
    }
}

// メイン関数
fun main() {
    // Zoo のインスタンスを作成
    val zoo = Zoo()

    // Lion と Elephant のインスタンスを作成
    /*【穴埋め問題7】
    ここに Lion クラスと Elephant クラスのインスタンスを作成するコードを書いてください。
    */

    // 動物を追加
    /*【穴埋め問題8】
    ここに動物を Zoo に追加するコードを書いてください。
    */

    // すべての動物情報を表示
    zoo.displayAllAnimals()

    // 各動物の鳴き声を表示
    /*【穴埋め問題9】
    ここに各動物の鳴き声を表示するためのコードを書いてください。
    */
}

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

この問題の解答と解説

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
interface Animal {
    // 動物の鳴き声を出すメソッド
    fun makeSound()
    // 動物の情報を表示するメソッド
    fun displayInfo()
}

// Animal インターフェースを実装する Lion クラスを定義
class Lion(val name: String, val age: Int) : Animal {
    // makeSound メソッドの実装
    override fun makeSound() {
        println("$name が吠えました: ガオー!")
    }

    // displayInfo メソッドの実装
    override fun displayInfo() {
        println("ライオン - 名前: $name, 年齢: $age 歳")
    }
}

// Animal インターフェースを実装する Elephant クラスを定義
class Elephant(val name: String, val age: Int) : Animal {
    // makeSound メソッドの実装
    override fun makeSound() {
        println("$name が鳴きました: パオーン!")
    }

    // displayInfo メソッドの実装
    override fun displayInfo() {
        println("ゾウ - 名前: $name, 年齢: $age 歳")
    }
}

// Animal を管理する Zoo クラスを定義
class Zoo {
    // 動物リストを保持するプロパティ
    private val animals: MutableList<Animal> = mutableListOf()

    // 動物を追加するメソッド
    fun addAnimal(animal: Animal) {
        animals.add(animal)
        // 動物が追加されたメッセージとその情報を表示
        println("動物が追加されました。")
        animal.displayInfo()
    }

    // すべての動物情報を表示するメソッド
    fun displayAllAnimals() {
        println("すべての動物の情報:")
        for (animal in animals) {
            animal.displayInfo()
        }
    }
}

// メイン関数
fun main() {
    // Zoo のインスタンスを作成
    val zoo = Zoo()

    // Lion と Elephant のインスタンスを作成
    val lion = Lion("レオ", 5)
    val elephant = Elephant("エリー", 10)

    // 動物を追加
    zoo.addAnimal(lion)
    zoo.addAnimal(elephant)

    // すべての動物情報を表示
    zoo.displayAllAnimals()

    // 各動物の鳴き声を表示
    lion.makeSound()
    elephant.makeSound()
}
Q
正解コードの解説

コードをブロックごとに分割して解説します。

インターフェースの定義

interface Animal {
    fun makeSound()
    fun displayInfo()
}
  • interface: Kotlinではインターフェースをinterfaceキーワードで定義します。
  • メソッドの宣言: makeSounddisplayInfoは抽象メソッドです。具体的な処理はここでは定義されず、実装するクラスがそれを担います。

Lion クラスの定義

class Lion(val name: String, val age: Int) : Animal {
    override fun makeSound() {
        println("$name が吠えました: ガオー!")
    }
    override fun displayInfo() {
        println("ライオン - 名前: $name, 年齢: $age 歳")
    }
}
  • class Lion: ライオンを表すクラス。
  • Animal の実装: Lion クラスは Animal インターフェースを実装(:を使用)しています。
  • override: インターフェースで定義されたメソッドを具体的に実装する際に使用します。

Elephant クラスの定義

class Elephant(val name: String, val age: Int) : Animal {
    override fun makeSound() {
        println("$name が鳴きました: パオーン!")
    }
    override fun displayInfo() {
        println("ゾウ - 名前: $name, 年齢: $age 歳")
    }
}
  • class Elephant: ゾウを表すクラス。
  • Animal の実装: Elephant クラスも Animal を実装し、ゾウに特化した動作を提供します。

Zoo クラスの定義

class Zoo {
    private val animals: MutableList<Animal> = mutableListOf()
    fun addAnimal(animal: Animal) {
        animals.add(animal)
        println("動物が追加されました。")
        animal.displayInfo()
    }
    fun displayAllAnimals() {
        println("すべての動物の情報:")
        for (animal in animals) {
            animal.displayInfo()
        }
    }
}
  • Zoo クラス: 動物園を管理するクラス。
  • MutableList<Animal>: 動物のリストを管理します。Animal型を指定することで、動物として扱えるオブジェクトだけをリストに追加できます。
  • addAnimal: 動物をリストに追加しその情報を表示します。
  • displayAllAnimals: リスト内のすべての動物の情報を表示します。

メイン関数

fun main() {
    val zoo = Zoo()
    val lion = Lion("レオ", 5)
    val elephant = Elephant("エリー", 10)

    zoo.addAnimal(lion)
    zoo.addAnimal(elephant)

    zoo.displayAllAnimals()

    lion.makeSound()
    elephant.makeSound()
}
  • val zoo = Zoo(): 動物園のインスタンスを作成します。
  • LionElephant: 動物のインスタンスを作成します。
  • addAnimal: 動物園に動物を追加します。
  • displayAllAnimals: すべての動物の情報を表示します。
  • makeSound: 各動物の鳴き声を表示します。
Q
サイト改善アンケート & ご指摘/ご質問

本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などを アンケート 形式でお伺いしています。

また記事の内容に関する ご指摘ご質問 もお待ちしています。

1.このサイトをどのように活用していますか?また、今後どのように活用したいですか?
5.気になっているサービス・商品があれば教えてください。
※ 特定の記事に関する内容の場合は、記事番号(レッスン〇-〇)をご記入願います。

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました