#■ジェネリック型とは
具体的なデータ型に依存しない,抽象的かつ汎用的なコードを書けるようにする手法
つまりString型とかInt型とか何の型でも使える様にする事
▼例:配列,コレクション
配列とかコレクションは何の型でも入ると思います。
ジェネリック型を使用しているからです。
逆に入る型を決める事もできました!!
場合によっては型を決めた方が安全性が高まるため。
//Int型しか入れないよ。
val aaa: mutableList<Int> = mutableListOf(1,2,3)
###■ジェネリックプログラミングが使われている例
▼Tはクラスの定義時には何でも入る型の事。 名前は任意 TやEが多い
型引数と呼ばれる。
引数の型
戻り値の型
として使える。
■インスタンス生成時にTに型を指定してクラス内部の型を制限する。
クラス内部のTは全て制限した型になる!!
class Hoge<T>(var value: T) {
fun aaa(): T {
return value
}
}
val hoge1 = Hoge<String>("こんにちわ")
val hoge2 = Hoge<Int>(2)
//型推論もできる。
val hoge3 = Hoge("よろしく")
println(hoge1.aaa()) //結果: こんにちわ
println(hoge2.aaa()) //結果: 2
hoge1.value = 3 //結果: エラー インスタンス生成時にvalueはstring型っていいましたやん!むりでっせ!!となる。
hoge3.value = 3 //結果: エラー 型推論してるだけ。クラスのTは全てStringに制限されている。
#■渡せる型を制限したい。
▼T:クラス名
書いたクラスまたは派生クラスのみを渡せる。
open class Hoge() {}
class Foo(): Hoge() {
val hello = "こんにちわ"
}
//<T:クラス名指定>
class Generic<T: Hoge>(var aaa: T) {
fun get(): T {
return aaa
}
}
//クラス名を指定されているので指定されたクラスかその親クラスのみ指定する。
val g1 = Generic<Foo>(Foo())
println(g1.get().hello) //結果: こんにちわ
val g2 = Generic<String>("はい") //結果: エラー