ジェニーリックとタイプ不変性


ジェニーリック


コトリンを勉強していたとき、ジェニーリックの概念が現れた.
実際、以前javaを勉強していたときは、一度は議論した概念でしたが、特に考えずに閲覧しました.今から見れば、全く分からない概念になった.そこで、この機会に整理しておきたいと思います.
まず辞書の意味を確認します.
ウィキペディアでジェニーンリックを検索すると、以下のような内容が出てきます.

1つの値が複数の異なるデータ型を有することができる技術に重点を置くことで、データ型に依存せずに再利用性を向上させるプログラミング方法.
難解.
ジェニリック氏は、コードの再使用を防止し、タイプの安定性を低下させる措置だと述べた.(例えば、値をパラメータとしてAny[JavaではObject]]から受信した場合→タイプ安定性の低下)
したがって、Genericを使用して、複数のデータ型を使用できるコードを記述することができる.
実際、すべてのプログラミングが文字で読むのは理解できません.サンプルで検証します.

タイプ不変性


まず,Freitクラスとそれをそれぞれ継承するBannaクラスとOrangeクラスを作成する.
タイプ不変性の例
open class Fruit
class Banana : Fruit()
class Orange : Fruit()

fun main() {
    fun receiveFruits(fruits: Array<Fruit>) {
        println("Number of fruits: ${fruits.size}")
    }

    val bananas:List<Banana> =listOf()
    receiveFruits(bananas)
}
上記のコードを入力することで、コンパイルエラーを確認できます.

関数のパラメータは、Arrayタイプをパラメータとして使用することが望ましいが、Arrayタイプがパラメータに組み込まれているため、タイプ不一致コンパイルエラーをチェックすることができる.
実際、ジェニーリックに概念がある前に、私はそれが当たり前だと知っていました.受け継がれた概念自体が子に親に関する情報があるので、Arrayを通して伝えてもバナナには果物に関する情報があります.
しかし、事実はそうではない.
これは、コトリン、ジェニーンリックのタイプの不変性の概念によって発生した状況です.
では、このタイプの不変性がどのような理由で必要かをサンプルコードで決定します.
タイプ不変性が必要な理由の例コード
open class Fruit
class Banana : Fruit()
class Orange : Fruit()

fun main() {
    val bananas: Array<Banana> = arrayOf(Banana())
    receiveFruits(bananas)
}

fun receiveFruits(fruits: Array<Fruit>) {
   fruits[0] = Orange() // 바나나 배열에 오렌지를 넣으면 문제가 됨
}
ArrayオブジェクトをパラメータとしてArrayを受信するパラメータに渡すことができる場合、Bannaを含む果物にOrangeオブジェクトが含まれ、問題が発生します.BannaとOrangeは同じタイプと見なされないからです.
すなわち,コトリンではBannaがFruitを継承してもArrayをArrayに渡すことができず,Generickのタイプを安定させることができる.しかし、次のコードを見てみましょう.
open class Fruit
class Banana : Fruit()
class Orange : Fruit()

fun main() {
    val bananas: List<Banana> = listOf(Banana(),Banana())
    receiveFruits(bananas)
}

fun receiveFruits(fruits: List<Fruit>) {
    println(fruits.size) // 2
}
以上のコードは正常に動作しています.私はただArrayをlistに変えただけです.
理由を知るためには、まずコートリンでのArrayとListを知る必要があります.
Arrayはコトリンで可変とされている.これに対して、Listは不変と見なされる.これを検証するために、ArrayドキュメントとListドキュメントをそれぞれチェックします.
Array-ドキュメント

リスト→ドキュメント

リストの宣言簿をチェックすると、リストとして宣言が表示されます.逆に、ArrayはArrayとして宣言される.この両者の違いはoutというキーワードがあるかどうかです.
この件については、後で検討します.
まず、リストはListであるため、cottlinコンパイラは共変性を許可し、上記のコードを許可する.
共変性については、後で話します.