Help us understand the problem. What is going on with this article?

Kotlinでジェネリクス、基本から応用-クラス定義からメソッド、多重実装まで-

More than 1 year has passed since last update.

はじめに

Kotlinでアプリを作ろう!と思い開始したのですが、Utilやhelperを作るためにジェネリクスと戯れていたら一日が終わっていました。
まだあまりKotlinのジェネリクスの記事が無いようなので、調べたり試したりした内容を記そうと思います。
適当な感じでjavaとの例で比較します。
こういうのもあるよ!というのがあれば教えていただければと思います。

基本

クラス・メソッドのジェネリクス

javaと変わらない

java
public abstract class Sample<T> {
    abstract T create();

    abstract void parameter(List<T> list, T t);
}
kotlin
abstract class Sample<T> {
    abstract fun create(): T

    abstract fun parameter(list: List<T>, t: T)
}

staticメソッド

companion objectのメソッドの中でジェネリクスを使う

java
class Smaple{
    public static <T> void sampleMethod(List<T> tList) {
    }
}
kotlin
class Sample {
    companion object {
        fun <T> sampleMethod(tList: List<T>) {
        }
    }
}

継承や実装制約を付ける場合

継承と同じように、「:」を利用する。
クラスとstaticメソッド両方一緒に記載。

java
public class Sample<T extends View> {
    public static <L extends View.OnClickListener> void setListener(L l){
    } 
}

kotlin
class Sample<T : View> {
    companion object {
        fun <L : View.OnClickListener> setListener(l: L) {
        }
    }
}

応用

多重実装

where句を利用する

java
public class Sample<T extends View & View.OnClickListener> {
    public static <L extends View & View.OnClickListener> void setListener(L l) {
    }
}
kotlin
class Sample<T> where T : View, T : View.OnClickListener {
    companion object {
        fun <L> setListener(l: L) where L : View, L : View.OnClickListener {
        }
    }
}

ちなみに、下のようにも書けるが、警告が出る

kotlin
class Sample<T : View> where T : View.OnClickListener {
    companion object {
        fun <L : View> setListener(l: L) where L : View.OnClickListener {
        }
    }
}

if a type parameter has multiple constraints, they all need to be replaced in the 'where' clause.
型パラメータに複数の制約がある場合、それらはすべて 'where'句で置き換える必要があります。

一つの場合でもwhere句は利用可能

継承や実装制約を付ける場合での例をwhereで書く。

kotlin
class Sample<T> where T: View {
    companion object {
        fun <L> setListener(l: L) where L : View.OnClickListener {
        }
    }
}

一つの場合は「:」の方が分かりやすそうだが、クラスやインターフェース名が長い場合はいいのかも。

morayl
主にAndroidアプリ開発をしています。 アプリエンジニアなのにコードの効率化が好きで、良くジェネリクスと戯れています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away