Kotlin classの例

Kotlin

言語なんてのは、その場面ゝで考えて納得(ここが重要)して染みついていくものだ。
コード補間がIDEの機能標準となってやたら長いクラスやメソッド名など記憶できるわけはない。
確かやったかなを右脳に残し、デジャブとなればしめたもの。
感性で思い出し検索し、これだったなをコピペ。それを手直しが正しいやり方だ。
学校で無理繰りやらせるための記憶を試すような問題はもはや意味をなさない。
時代は大きく変わっている。社会のシステムはまったく追いついてこないからちぐはぐだ。

//-- Example of Kotlin ---

//基底クラスAnimal。openを付けないと継承できない
open class Animal{}

//Animalを継承したCatクラス。extendsではなく:で基底クラスを指定する
class Cat: Animal(){}

//スマートキャストサンプルのためのクラス群
data class Point(val X:Double = 0.0,  val Y:Double = 0.0)
data class Color(val R:Int = 0, val G:Int = 0, val B:Int = 0)

//基底クラス
open class Person(val firstName: String, val lastName: String = ""){
  //openキーワードでオーバーライド可能に
  open fun print(){
    println("お名前: ${firstName} ${lastName}")
  }
}

//継承クラス。継承元のコンストラクタを指定
class BussinessPerson(firstName: String, lastName: String = "", val age: Int) : Person(firstName, lastName){
  //メソッドのオーバーライド
  override fun print(){
    println("お名前: ${firstName} ${lastName}, 年齢: $age")
  }
}

//抽象クラス
abstract class Vehicle{
  //抽象メソッド
  abstract fun run()
}

//抽象クラスの具象化
class Car : Vehicle(){
  //抽象メソッドのオーバーライド
  override fun run(){
    println("Running!")
  }
}

//インタフェースの定義例
interface Flyable{
  fun fly()
}

//インタフェースの実装例
class Airplane: Vehicle(), Flyable{
  override fun run(){
    println("Running on runway!")
  }
  //インタフェースのメソッドを実装(実装しないとコンパイルエラー)
  override fun fly(){
    println("Flying!")
  }
}

//実装を持つインタフェースの定義例
interface Stoppable{
  fun stop(){ print("Stopped slowly...") }
}

//同名のstopメソッドを持つインタフェース
interface Stoppable2{
  //名前のぶつかるメソッド
  fun stop(){ print("Stopped suddenly!!!") }
  //名前のぶつからないメソッド
  fun crash(){ print("Crash!!!") }
}

//実装を持つインタフェースの実装例
class StoppableVehicle: Vehicle(), Stoppable{
  override fun run(){
    println("Running!")
  }
}

//同じ名前のメソッドを持つインタフェースを複数実装した例
class StoppableVehicle2: Vehicle(), Stoppable, Stoppable2{
  override fun run(){
    println("Running!")
  }
  //stopメソッドを定義しないとコンパイルエラーになる
  override fun stop(){
    print("Original stop implementation!")
    super<Stoppable>.stop()  //Stoppableのデフォルト実装を呼び出す
    super<Stoppable2>.stop() //Stoppable2のデフォルト実装を呼び出す
  }
}


//プロパティを持つ(!)インタフェース
interface Limiter{
  //プロパティを定義できるが、実際にはabstractとして扱われる
  val maxSpeed: Int

  //デフォルト実装からプロパティを参照できる
  fun boost(speed : Int){
    if(speed > maxSpeed){
      println("Overspeed!")
    }else{
      println("Boosted to $speed")
    }
  }
}

//実装を持つインタフェースの実装例
class CarWithLimiter: Vehicle(), Limiter{
  //インタフェースのプロパティを明示的に実装する必要あり
  override var maxSpeed : Int = 100
  override fun run(){
    println("Running!")
  }
}

fun main(args:Array<String>) {
    //継承したクラスの作成とメソッド呼び出し
    var bussinessPerson = BussinessPerson("Tanaka", "Taro", 22)
    bussinessPerson.print() //「お名前: Tanaka Taro, 年齢: 22」

    //抽象クラスはインスタンス化できない
    //val vehicle = Vehicle() →エラー

    //継承したクラスのインスタンス化と呼び出し
    val car = Car()
    car.run()

    //インタフェースを実装したクラスの使用
    val airplane = Airplane()
    airplane.run() //「Running on runway!」
    airplane.fly() //「Flying!」

    //プロパティを持つインタフェースを実装したクラスの使用
    val carWithLimiter = CarWithLimiter()
    carWithLimiter.run()       //「Running!」
    carWithLimiter.boost(120)  //「Overspeed!」

    //プロパティの内容がインスタンスごとであることを確認
    //もう一つインスタンスを作成
    val carWithLimiter2 = CarWithLimiter()
    //1つ目のインスタンスのmaxSpeedプロパティを書き換える
    carWithLimiter.maxSpeed = 200
    carWithLimiter.boost(120)  //「Boosted to 120」maxSpeedが書き換わっているので問題無くブースト可能
    carWithLimiter2.boost(120)  //「Overspeed!」2つ目のインスタンスのmaxSpeedは書き換わっていない

    //デフォルト実装の競合解決例
    var stoppableVehicle2 = StoppableVehicle2()
    stoppableVehicle2.stop() //「Original stop implementation!Stopped slowly...Stopped suddenly!!!」

    //Cat型(Animal型を継承)のインスタンス
    val cat = Cat() 
    val animal = cat as Animal //Animal型にキャスト
    //val animal2 = (Animal)cat //この形式はエラー
    println(animal)

    //スマートキャストの呼び出し
    val color = Color(255,255,0)
    action(color)
    val point = Point(10.5,12.3)
    action(point)

    val obj = Color(255,255,0)
    val obj2 = obj as Any
    println(obj2)
}

//スマートキャストの例
fun action(something: Any){
  when(something){
    is Point -> println("Point: ${something.X}, ${something.Y}")
    is Color -> println("Color: [${something.R},${something.G},${something.B}]")
  }

  if(something is Point){
    println("Point: ${something.X}, ${something.Y}")
  }else if(something is Color){
    println("Color: [${something.R},${something.G},${something.B}]")
  }
}
No tags for this post.
タイトルとURLをコピーしました