抽象クラスとインターフェースについて | Kotlin


抽象クラスとインターフェースについて、
やっと納得できた！！！(はず)

今まで調べて雰囲気理解して見様見真似で使用して、また調べて...を繰り返してた...(抽象クラスに限ったことではないけど)

なので記録として残しておく:unamused:
これで全然違うよって思ったら、教えてください。お願いします。


## 1.抽象クラスと抽象メソッド
#### 抽象クラスとは
・継承されることを目的としたクラス
・インスタンス化できないクラス(抽象的であるので具体化は無理)
#### 抽象メソッドとは
・中身の実装ができないメソッド
・抽象クラスを使用したクラスは、強制的に使うことになる

#### 定義方法
```kotlin:MainActivity.kt
abstract class Engine(name:String){
  var engineName = name  
  abstract fun speed():Int
fun breake(){
 }
}
```
・"abstract"を先頭に付ける("open"は不要)
・コンストラクタを設定できる
・プロパティに値を持てる
・抽象的なものには先頭に"abstract"を付ける
・通常のメソッドも、抽象メソッドも定義可能
・抽象メソッドはパラメータと戻り値の型の指定はできるが中身の実装はできない

#### 抽象クラスを継承する方法
```kotlin:MainActivity.kt

class MainActivity : AppCompatActivity() {
 
override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)       

 Car().speed()

}

//抽象クラスと抽象関数
abstract class Engine(name:String){    
 var engineName = name  

 abstract fun speed():Int

}

//エンジン抽象クラスを継承するクラス
class Car():Engine("ferrari"){    
 var speedResult = 0

 override fun speed(): Int {
  if ( engineName== "ferrari" ){
    speedResult = 100
  Log.d("speed",speedResult.toString())           
  return speedResult
}
  speedResult = 30        
  Log.d("speed",speedResult.toString())        
  return speedResult
 }
}

```
結果：100
・クラス名の後に"：抽象クラス名()"
・抽象的なもの(abstractつけたやつ)は、overrideして使用
・抽象メソッドの中身はここで具体的に使いたいように記述

#### 注意点

```kotlin:
class Car():Engine("ferrari"){
 val engineClass = Engine("a")
}
```

・抽象クラスはインスタンス化できない
(エラー：Cannot create an instance of an abstract class)

```kotlin:
abstract class Engine(name:String){
 abstract fun speed():Int
}

abstract class Brake(){
}

Class Car():Engine("ferrari"),brake(){
}
```
・多重継承はできない
(エラー：Only one class may appear in a supertype list)

```kotlin:

class Car():Engine("ferrari"){
//抽象クラスで定義した抽象関数をコメントアウト
//override fun speed(): Int {
//  if ( engineName== "ferrari" ){
//   speedResult = 100
//   return speedResult
//  }
//   speedResult = 30
//   return 30
//    }
}

```
・抽象メソッドは必ずoverrideする
(エラー：Class 'Car' is not abstract and does not implement abstract base class member)

## 2.インターフェース
#### インターフェースとは
・異なる種類のクラス同士に共通した処理がある時、共通項として定義しておける
・継承して使われるものではあるけど、異なる種類のクラスでも継承が許される

#### 定義方法
```kotlin:
interface Write{
 val helloString:String
 fun print(){
 val hello = helloString
 Log.d("inter",hello)
 }
}
```
・"interface"をインターフェースの前につける
・"open"や"abstract"は不要
・プロパティの定義はできるが、ゲッターなしでは値を持てない

```kotlin:
val helloString:String
get() = "Hello"
```

#### インターフェースを継承する方法
```kotlin:
class MainActivity : AppCompatActivity() {
 override fun onCreate(savedInstanceState: Bundle?) {        
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)

 Job().print()   
 }
}

interface Write{    
 val helloString:String
 fun print(){
  val hello = helloString
  Log.d("printer",hello)
  }
}

class Job():Write{
 override val helloString: String
 get() = "ハロー"
 override fun print() {
 super.print()
 }
}
```
結果：ハロー
・クラス名の後に"：インターフェース名"
・抽象的なものはoverride(プロパティやメソッド)


#### 注意点

```kotlin:
interface Write(string:String){}
```
・コンストラクタはもてない
(エラー：An interface may not have a constructor)

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

まずは私自身が一番納得できた違いについて。

**抽象クラスは、
継承されることを目的に作られたクラス。**
**インターフェースは、
異なる種類のクラスでも継承が許された定義的なやつ。**

私は継承って部分についても知識があいまいなので、記録:zipper_mouth:
・スーパークラス(継承元)を拡張したクラスが継承先のクラスである
・サブクラス(継承先)はスーパークラスの一部である
などと書いてあるのでそんな関係性なんだと思う。
炭酸クラスと紅茶クラスはどちらも飲料クラスを継承しています。的な...


じゃあ異なる種類のサブクラスたちが同じ機能を持ちたい！
ってなったときは？ってなると思うんだけど、
そんなときにはインターフェース。
炭酸クラスと車クラスは全く関係のないクラス同士ではあるけど、
”量をはかる”という共通点があったらそれはインターフェースを利用して
一部分だけ共有しようね。的な..？

#### 違い
・抽象クラスはabstractが必要だが、インターフェースは不要
・抽象クラスは多重継承不可、インターフェースは可
・抽象クラスはプロパティに値をもてる、インターフェースはゲッターが必要
・抽象クラスはコンストラクタを持てる、インターフェースは持てない
・抽象クラスは継承先が同系統のクラス、インターフェースは異なる系統でも可
(抽象クラスは継承のためのクラスだと考えると、継承とは継承先は継承元の一部であるとなるから)

#### 共通点
・インスタンス化できない
・openが不要
・抽象的なものは継承先クラスでオーバーライド

## まとめ

抽象クラスインターフェースの前に継承について、
あんまりよくわかってなかった(今も怪しいかもしれないけど、前よりはマシと願う:pray:)
だから書き方の違いはいろいろ記事見たらわかるけど、腑に落ちなかったのかも。

使い分けどうしたら良いんだろう...?
こんな時はみんなインターフェース使ってるっぽいから真似しとこ...とかってなってた。

他にもなあなあにしてることあるから、潰していきたいです。
というかこの記事も正しいかは分からないけど、とりあえず今の自分の解釈ということで


#### 参考記事

①https://pouhon.net/kotlin-interface/3357/
②https://kotlin-study.com/abstractclass-interface/