Kotlin Referenceを読んで＋aしてまとめてみる。ークラス、コンストラクタ、クラスのインスタンス生成、クラスメンバー

この記事は、以下の「Kotlin Reference」日本語版を
元にしています。

#Kotlin Reference　（日本語）
https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/classes.html

###前書き
Kotlin初心者が、書いております。
ここが違う、もっとわかりやすく書いて欲しい等のご指摘いただけると助かります。
Kotlin Referenceを読んで、初めてKotlinを学ぶ方が、
こう書けばもっとうまく伝わるかな？　理解しやすいかな？
と考えながら書いております。
その為、内容はKotlin Reference ＋a 程度です。

##クラスと継承　クラス〜クラスメンバまで

##クラス

classキーワードでクラスを宣言する。

例１:

```
class Invoice{}
```

クラスの構成要素は、

①クラス名
②クラスヘッダ（その型パラメータ、主コンストラクタ等）
③波括弧で括られたクラス本体

上記①〜③で構成されます。

・②クラスヘッダと③クラス本体は両方とも必須ではない。
　（省略が可能）
・クラスに本体がない場合は、波括弧{}を省略することができます。
　以下は、波括弧{}を省略の参考例

例２:

```
class Empty
```

例３:

```
class Example(name : String) {
  println("Hello $name")
}
```

上記、３つを表にすると

|   | ①クラス名 | ②クラスヘッダ | ③波括弧で括られたクラス本体 |
|----|-------|---------|----------|
| 例1 | Invoice    |   ここでは省略 |    { }    |
| 例2 | Empty    |   ここでは省略 |    ここでは省略  |
| 例3 | Example    | (name : String) | println("Hello $name")  |

##コンストラクタ

Kotlinのコンストラクタには大きく分けて２つが存在する。

①プライマリコンストラクタ
②セカンダリコンストラクタ

上記、２つをクラスで持つことができます。

・プライマリコンストラクタは、クラスヘッダの一部です。
　クラス名（型パラメータをつけることもできます）の後に書きます。
・セカンダリコンストラクタは、クラス本体内に複数書けます。

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

プライマリコンストラクタ基本例：

```
class Person constructor(firstName: String) {
}
```

・プライマリコンストラクタが、
　[アノテーション](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/annotations.html)、[可視性修飾子](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/visibility-modifiers.html)を持っていない場合は、 
　constructorのキーワードを省略することができます。

以下、省略例

```
class Person(firstName: String) {
}
```
・プライマリコンストラクタには、コードを書けない。
　初期化コードは、initキーワードが付いている初期化ブロック内に書くことができます。

```
class Customer(name: String) {
    init {
        logger.info("Customer initialized with value ${name}")
    }
}
```


・プライマリコンストラクタの引数を初期化ブロック内で使用することができる。
・クラス本体内で宣言されたプロパティの初期化処理で使用することができる。


```
class Customer(name: String) {
    val customerKey = name.toUpperCase()
}
```


プロパティの宣言と初期化をプライマリコンストラクタで行うことが出来ます。
書き方は、以下になります。


```
class Person(val firstName: String, val lastName: String, var age: Int) {
  // ...
}
```

通常のプロパティとほとんど同じ方法のように、
プロパティは、プライマリコンストラクタの中で、

可変値（ミュータブル） ( var ) または
固定値（イミュータブル） ( val ) で宣言することができます。


もしコンストラクタが、[アノテーション](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/annotations.html)、[可視性修飾子](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/visibility-modifiers.html)を持つ場合は、 
constructorキーワードが必要で修飾子はその前に置かれます。

```
class Customer public @Inject constructor(name: String) { ... }
```

上記、例を表にすると以下のようになります。

|   | ①クラス名 | ②可視性修飾子 | ③アノテーション | ④constructor キーワード | ⑤プライマリコンストラクタ |
|----|-------|---------|----------|---|---|
| 例 | Customer  |  public | @Inject  | constructor | (name: String)|

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

セカンダリコンストラクタを使う場合は、
クラス内で、constructorキーワードと共にセカンダリコンストラクタを宣言することができます。

```
class Person {
    constructor(parent: Person) {
        parent.children.add(this)
    }
}
```

クラスがプライマリコンストラクタを持つ場合は、
セカンダリコンストラクタは、他のセカンダリコンストラクタを、
介してプライマリコンストラクタへ委譲する必要があります。 
同クラスの他コンストラクタへの委譲は、thisキーワードを用いて行う。

```
class Person(val name: String) {
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}
```

もし非抽象クラスが何もコンストラクタ（プライマリ、セカンダリ共に）を宣言しなければ、
プライマリコンストラクタが引数無しで生成されます。
その場合のコンストラクタの可視性はpublicになります。
public以外の可視性修飾子をつけたい場合は、明示的に宣言する必要があります。

```
class DontCreateMe private constructor () {
}
```

注意:
JVMでは、プライマリコンストラクタの全ての引数がデフォルト値を持つなら、
コンパイラは引数無しコンストラクタを追加で生成し、そのコンストラクタはデフォルト値を使用します。

その為、JacksonやJPAのように引数が無いコンストラクタを通してクラスインスタンスを作るようなライブラリを、
Kotlinで使いやすくなります。

```
class Customer(val customerName: String = "")
```

##クラスのインスタンス生成

クラスのインスタンスを生成するには、
コンストラクタを関数のように呼び出せます。

```
val invoice = Invoice()

val customer = Customer("Joe Smith")
```

注意:
Kotlinは newキーワードを持たないことに注意してください。

ネストされたクラス、インナークラス、そして匿名のインナークラスの生成は、
ネストされたクラスの中に記述されています。

##クラスメンバ

クラスメンバについては、リファレンスに準じて割愛します。
この記事では、

以下、リンクを参照のこと

クラスは以下を含めることができます。

-コンストラクタと初期化ブロック
-[関数](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/functions.html)
-[プロパティ](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/properties.html)
-[ネストされたインナークラス](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/nested-classes.html)
-[オブジェクトの宣言](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/object-declarations.html)

##まとめ

もっと、綺麗にまとめたり、図を使ってまとめたりしたいと思いましたが、
アウトプットを先にしてしまいたいと思いました。
理解が深まれば、追記、修正を考えています。

重ねてですが、
ここが違う、もっとわかりやすく書いて欲しい等のご指摘いただけると助かります。

Kotlinに触れる人のコードの理解の一助となれればと思います。
記事を読んでくださり、ありがとうございます。

##参考
Kotlin文法 - クラス、継承、プロパティ
https://qiita.com/k5n/items/35e76d79ee9de4effb89#%E3%82%AF%E3%83%A9%E3%82%B9

【Kotlin】コンストラクタの書き方
https://qiita.com/siroykht/items/862fd080bb18f1551aaa

Kotlinにおけるクラス、プロパティ、コンストラクタ、データクラス、シングルトン (2/3)
https://www.atmarkit.co.jp/ait/articles/1804/02/news009_2.html

[Android]Kotlinのコンストラクタと「init」（なぜ「init」が必要なのか）
https://minpro.net/kotlin-constructor-init