「勉強会に行ってみた!」第31回「第3回Kotlin勉強会@Sansan」
event

「勉強会に行ってみた!」
第31回「第3回Kotlin勉強会@Sansan」

2016.08.10

■Kotlinとは

Kotlinは、IntelliJ IDEAなどのIDEで有名なJetBrains社が開発した、JVMとAndroid向けのオブジェクト指向プログラミング言語です。
Javaとの親和性が高く、KotlinからJavaを呼び出すことも、JavaからKotlinを呼び出すこともできます。
1.0のリリースは2016年2月15日ですが発表は2011年7月20日なので、実は比較対象とされることの多いSwiftの登場以前からある言語で、現在、多くのデベロッパーが利用しています。

(井上純)
資料:発表当時のスライド(http://goo.gl/HdYO5G)

■乾杯でスタート

さて、今回は第3回Kotlin勉強会に参加しました。
第1回はAndroidに限定した勉強会でしたが、前回からAndroidに限らず広くKotlinに関するLTを発表する勉強会となり、今回もAndroidエンジニアに限らず様々な言語を扱うプログラマーが集まっていました。
発表者によるLTが中心の勉強会は、一般的に学校の授業を聞くような雰囲気になることが多いのですが、今回の会場は観葉植物に囲まれ、発表の前から参加者にお酒とおつまみが用意されていて、和やかなムードが印象的でした。
そして、Kotlinエバンジェリストの長澤太郎さんの乾杯でスタート!

■KotlinのClass Delegationおさらい

全てのLTについて書くと膨大になってしまいますので、今回はKotlinエバンジェリストである長澤太郎さんのLTを紹介します。

さて、Androidエンジニアには、プログラミングをする際に利用したいクラスをスーパークラスとして継承し、サブクラスでカスタマイズして使うという方は結構多いのではないでしょうか?

■差分プログラミング

差分プログラミング

class CountingHashSet<E> : java.util.HashSet<E>() {
  var addCount: Int = 0
   private set

  override fun add(element: E): Boolean {
   addCount++
   return super.add(element)
  }

  override fun addAll(elements: Collection<E>): Boolean {
   addCount += elements.size
   return super.addAll(elements)
  }
}

このようなプログラミングのことを差分プログラミングと言いますが、Javaプログラマのバイブル「Effective Java」の項目16に「継承よりコンポジションを選ぶ」と書かれています。
上記の例では「addAll」が呼ばれると、スーパークラスで「add」を利用しているため、オーバーライドした「add」が呼ばれてしまいます。結果、想定した「addCount」を得ることはできません。この場合の解決方法として「addAll」ではカウントしないという方法ももちろんありますが、これはスーパークラスの実装をプログラマが知っているということが前提になります。
この他にも継承を行うことで発生する問題として、スーパークラスとサブクラスを管理するプログラマが同一人物であれば良いのですが、そうでない場合にはスーパークラスに依存するため、自分がプログラムを書き換えていない場合でもスーパークラスの実装が変更されてしまうことで、意図しない動作を引き起こす可能性を孕んでいます。

■コンポジション

差分プログラミングが孕む問題は、「継承よりコンポジションを選ぶ」ことで解決します。

コンポジション

class CountingHashSet<E>(private val set: MutableSet<E>): MutableSet<E> {

  var addCount: Int = 0
  private set

  override fun add(element: E): Boolean {
   addCount++
   return set(element)
  }

  override fun addAll(elements: Collection<E>): Boolean {
   addCount += elements.size
   return set.addAll(elements)
  }

  ...他にオーバーライドするメソッドたち
 }

上記のように、継承していたスーパークラスを保持しインターフェースを利用することで、差分プログラミングでの実装上の問題点は解決されました。
しかし、不必要なオーバーライドすべきメソッドたちを記述する必要があり、ソースコードの見通しは良くありません。

■Class Delegation

コンポジションによる実装で新たに出来てしまった問題を解決する方法があります。
それがClass Delegationです。

Class Delegation
class CountingHashSet<E>(private val set: MutableSet<E>): MutableSet<E> by set {

  var addCount: Int = 0
  private set

   override fun add(element: E): Boolean {
    addCount++
    return set(element)
   }

   override fun addAll(elements: Collection<E>): Boolean {
    addCount += elements.size
    return set.addAll(elements)
   }
}

上記の例で言うところの「by set」がClass Delegationです。
by句によってMutableSetの実装をsetオブジェクトに委譲することで余分なオーバーライドメソッドを記述せずに実装を書けるようになります。

■まとめ

筆者は実際にJavaでプログラミングをする際、インターフェース実装で余分なメソッドの記述があるのを嫌って、主に継承によって実装を行ってきましたが、KotlinではClass Delegationによって見通しの良いプログラムを簡単に実装することができます。
他6名の方のLTも興味深い内容でした。Androidエンジニアに限らず、Scalalianの方やC#erの方の発表もありましたので興味のある方はスライドを見てみてはいかがでしょうか?

■ LT

原稿:井上純
qnoteシステム開発事業部所属。気分で色が変わる毛髪を有し、夏になるとスイカに擬態する。なお、オフィスには7匹の猫がいる

この記事はどうでしたか?

おすすめの記事

キャリアを考える

BACK TO TOP ∧

FOLLOW