SlideShare a Scribd company logo
1 of 23
Download to read offline
Scala の言語機能 – 継承による実装
           実装継承
                    実装のために行う継承(情報量増えてないゾ)
                    実装詳細を持つクラスを、利用したいクラスが継承
                            親クラスのように振る舞いたいわけではない!




https://lepidum.co.jp/            Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Java による素朴な例
           public class Counter {
             private int counter;
             public void addCounter() { counter++; }
             public int getCounter() { return counter; }
           }
           public class VisitorsCounter extends Counter {
             public void visit() { addCounter(); }
             public int getVisitorsNum() { return getCounter(); }
           }




https://lepidum.co.jp/         Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Java による素朴な例
                    問題点 1:実装詳細が外部に公開されてしまう
           VisitorCounter visitorCounter = new VisitorCounter();
           visitorCounter.visit();
           visitorCounter.addCounter(); // oops!




https://lepidum.co.jp/         Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Java による素朴な例
                    問題点 1:実装詳細が外部に公開されてしまう
                    問題点 2:意図しない polymorphism
                            Counter のように振る舞いたいわけではない
           Counter counter = new Counter(); // ok
           counter = new VisitorCounter(); // oops!




https://lepidum.co.jp/              Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Java による素朴な例
                    問題点 1:実装詳細が外部に公開されてしまう
                    問題点 2:意図しない polymorphism
                    問題点 3:複数の実装詳細を同時に扱えない
                            Java は単一継承のみ、多重継承はない
           public class Timer { … }
           public class Counter { … }
           public class VisitorCounter extends ??? // さてはて…




https://lepidum.co.jp/             Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           C++ の private/protected 継承
           class Counter {
              int counter_ = 0; // C++11 の member initialization
           public:
              void add() { counter_++; }
              int get_counter() const { return counter_; }
           };
           class VisitorsCounter : private Counter {
           public:
              void visit() { add(); }
              int get_visitors_num() const { return get_counter(); }
           };




https://lepidum.co.jp/         Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           C++ の private/protected 継承
                    実装詳細は外部に公開されない
                    意図しない polymorphism は発生しない
           VisitorCounter* visitor_counter = new VisitorCounter();
           visitor_counter->visit();
           // visitor_counter->add(); // error!
           // Counter* counter = visitor_counter; // error!




https://lepidum.co.jp/         Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           C++ の private/protected 継承
                    実装詳細は外部に公開されない
                    意図しない polymorphism は発生しない
                    複数の実装詳細を扱える…が、取扱注意




https://lepidum.co.jp/       Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           C++ の private/protected 継承
                    問題点:too complex!!!
                            解決:Java と同様、所有(composition)を利用する
                                 C++ の良いところは、良く考えられていることであり
                                 C++ の悪いところは、良く考えられ過ぎていることである
                                    詠み人知らず




https://lepidum.co.jp/                 Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           実装継承、よりも…
                    一般的には所有(composition)が望ましい
                            問題点 1:書くのが面倒…
           public class Foo {
             private ImplA implA;
             private ImplB implB;
             public Foo() { implA = new ImplA(); implB = new ImplB(); }
             public void implementedByA() { implA.something(); }
             public void implementedByB() { implB.something(); }
             public void implementedByAandB() {
               implA.something(); implB.something();
             }
           }


https://lepidum.co.jp/             Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           実装継承、よりも…
                    一般的には所有(composition)が望ましい
                            問題点 1:書くのが面倒…
                            問題点 2:実装詳細がカスタマイザブルでない
                                 解決: Dependency Injection(DI)
                                    問題点:書くのが面倒…(二度目)

                                       解決: DI Container

                                          問題点 1: 書くのが面倒(三度目)だし仰々しすぎ

                                          問題点 2: Java 以外であまり流行ってない


                            結論: Java ダメだこれ

https://lepidum.co.jp/                  Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           他の言語
                    Eiffel とか Python とか Common Lisp(CLOS) とか
                            色々な言語毎に、解決方法と問題点がある
                                このプレゼンはそれを書くにはなんかが少なすぎる
                            そもそもオブジェクト指向と呼ばれる物が多すぎる!
                                まとめたら論文にできそう
                                   なんならもうありそう




https://lepidum.co.jp/                Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotations と trait/mixin
           trait Counter {
             private var c: Int = 0
             def add() { c += 1 }
             def get: Int = c
           }
           class VisitorsCounter {
             self: Counter =>
             def visit() { add() }
             def getVisitors = get
           }




https://lepidum.co.jp/         Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotations と trait/mixin
                    trait/mixin とは…?
                            trait はざっくりいうと実装を持てる Java の interface
                                 abstract class ではないので、複数の trait を継承可能
                                 trait の継承を mixin と呼んだりする
           trait Counter {
             private var c: Int = 0
             def add() { c += 1 }
             def get: Int = c
           }




https://lepidum.co.jp/                   Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotation と trait/mixin
                    self type annotation とは…?
                            その型の具象的な値に対する型注釈
                                VisitorsCounter は Counter を継承しなければならない
           class VisitorsCounter {
             self: Counter => // this class is `implemented by` Counter!
             def visit() { add() }
             def getVisitors = get
           }

           // val counter = new VisitorsCounter // error!



https://lepidum.co.jp/                  Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotation と trait/mixin
                    お節介な型推論に御用心
                            型推論の方でもちょろっと触れます
           val counter = new VisitorsCounter with Counter // mixin! ok! …?
           counter.add() // oops! why is this valid?
                         // counter type is “VisitorsCounter with Counter”
                         // we should annotate type explicitly!
           val annotated: VisitorsCounter =
             new VisitorsCounter with Counter // ok!
           // annotated.add() // error!
           annotated.visit()




https://lepidum.co.jp/             Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotation と trait/mixin
                    複数の class を指定することも可能
                            正確には高々一つの class と任意個の trait
                                 より正確には class linearization の結(省略されました)
           class VisitorsCounter {
             self: Counter with Timer =>
             …
           }




https://lepidum.co.jp/                   Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotation と trait/mixin
                    とか不要で interface extraction でいいんじゃ?
                            Java でも解決だよね?
           trait VisitorsCounter { … }
           trait Counter { … }
           trait Timer { … }
           class VisitorsCounterImpl
             extends VisitorsCounter with Counter with Timer { … }
           val counter: VisitorCounter = new VisitorsCounterImpl




https://lepidum.co.jp/              Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotation と trait/mixin
                    とか不要で interface extraction でいいんじゃ?
                            問題点:実装詳細が変わるたびにコードの重複が発生
           trait PreciseTimer extends Timer { … }
           class VisitorsCounterImpl
             extends VisitorsCounter with Counter with Timer {
             … // implementation
           }
           class PreciseVisitorsCounterImpl
             extends VisitorsCounter with Counter with PreciseTimer {
             … // code duplication!
           }



https://lepidum.co.jp/            Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotation と trait/mixin
                    trait/mixin なら実装詳細を簡単に変更可能
                            コードの重複は発生しない
           class VisitorsCounter {
             self: Counter with Timer =>
             …
           }
           trait PreciseTimer extends Timer { … }
           class PreciseVisitorsCounter
             extends VisitorsCounter with Counter with PreciseTimer
           // no code duplication!




https://lepidum.co.jp/            Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotation と trait/mixin
                    実装持ってるもの多重継承して問題ないの?
                            Class linearization により継承ツリーは linearize される
                                 結果、多重継承のように見えていたものは単一継承になる
           abstract class AbsIterator { … }
           trait RichIterator extends AbsIterator { … }
           class StringIterator extends AbsIterator { … }
           class Iter extends StringIterator with RichIterator { … }
           // Iter の継承ツリーは以下のように linearize される
           // Iter -> RichIterator -> StringIterator -> AbsIterator




https://lepidum.co.jp/                 Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           Scala の self type annotation と trait/mixin
                    trait は強力な言語機能、他にも色々有用
                            リッチインターフェースの提供
                            stackable な open recursion の実現
                                 abstract override なんてニッチなものも…
                    強力さ故の代償も
                            Separate Compiliation 的には困った機能
                                 詳細は javap –c すれば分かります。手前味噌ですが参考




https://lepidum.co.jp/                   Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential
Scala の言語機能 – 継承による実装
           まとめ
                    Scala では以下の機能により
                            self type annotation による implemented by の表明
                            trait/mixin による柔軟な実装の提供
                    設計意図が伝わり安く、使い安い設計が可能
                            Java ほど貧弱でなく、C++ ほど複雑でなく
                            他の言語機能と組み合わせればもっと良くなるよ!




https://lepidum.co.jp/                 Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved.   Confidential

More Related Content

Similar to 第一回社内 Scala 勉強会(一部抜粋)その 2

Application Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternApplication Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternAtsushi Kambara
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発papamitra
 
名古屋Ruby会議01 A3.製造業向け3Dデータ変換ソリューションにおけるRuby活用事例
名古屋Ruby会議01 A3.製造業向け3Dデータ変換ソリューションにおけるRuby活用事例名古屋Ruby会議01 A3.製造業向け3Dデータ変換ソリューションにおけるRuby活用事例
名古屋Ruby会議01 A3.製造業向け3Dデータ変換ソリューションにおけるRuby活用事例Shigeru UCHIYAMA
 
Scalaでのプログラム開発
Scalaでのプログラム開発Scalaでのプログラム開発
Scalaでのプログラム開発Kota Mizushima
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門Makoto Fukuhara
 
Swift 2 (& lldb) シンポジウム
Swift 2 (& lldb) シンポジウムSwift 2 (& lldb) シンポジウム
Swift 2 (& lldb) シンポジウムYuichi Yoshida
 
言語アップデート -Scala編-
言語アップデート -Scala編-言語アップデート -Scala編-
言語アップデート -Scala編-Kota Mizushima
 
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorb
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorbRuby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorb
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorbKoichiro Sumi
 
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]David Buck
 
【16-D-4】3分ではじめるスマホアプリのビジュアル開発
【16-D-4】3分ではじめるスマホアプリのビジュアル開発【16-D-4】3分ではじめるスマホアプリのビジュアル開発
【16-D-4】3分ではじめるスマホアプリのビジュアル開発hmimura_embarcadero
 
コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)
コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)
コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)NTT DATA Technology & Innovation
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/AndroidセキュアコーディングMasaki Kubo
 
Go 製リアルタイムサーバーの Kubernetes での運用について
Go 製リアルタイムサーバーの  Kubernetes での運用についてGo 製リアルタイムサーバーの  Kubernetes での運用について
Go 製リアルタイムサーバーの Kubernetes での運用についてKairiOkumura
 
Swiftによる関数型プログラミング超入門
Swiftによる関数型プログラミング超入門Swiftによる関数型プログラミング超入門
Swiftによる関数型プログラミング超入門Hisakuni Fujimoto
 
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説Akira Inoue
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Nextdynamis
 

Similar to 第一回社内 Scala 勉強会(一部抜粋)その 2 (20)

ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
Application Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternApplication Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD Pattern
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
 
名古屋Ruby会議01 A3.製造業向け3Dデータ変換ソリューションにおけるRuby活用事例
名古屋Ruby会議01 A3.製造業向け3Dデータ変換ソリューションにおけるRuby活用事例名古屋Ruby会議01 A3.製造業向け3Dデータ変換ソリューションにおけるRuby活用事例
名古屋Ruby会議01 A3.製造業向け3Dデータ変換ソリューションにおけるRuby活用事例
 
Scalaでのプログラム開発
Scalaでのプログラム開発Scalaでのプログラム開発
Scalaでのプログラム開発
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門
 
Swift 2 (& lldb) シンポジウム
Swift 2 (& lldb) シンポジウムSwift 2 (& lldb) シンポジウム
Swift 2 (& lldb) シンポジウム
 
言語アップデート -Scala編-
言語アップデート -Scala編-言語アップデート -Scala編-
言語アップデート -Scala編-
 
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorb
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorbRuby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorb
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorb
 
The evolution of c#
The evolution of c#The evolution of c#
The evolution of c#
 
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
 
【16-D-4】3分ではじめるスマホアプリのビジュアル開発
【16-D-4】3分ではじめるスマホアプリのビジュアル開発【16-D-4】3分ではじめるスマホアプリのビジュアル開発
【16-D-4】3分ではじめるスマホアプリのビジュアル開発
 
コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)
コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)
コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/Androidセキュアコーディング
 
Go 製リアルタイムサーバーの Kubernetes での運用について
Go 製リアルタイムサーバーの  Kubernetes での運用についてGo 製リアルタイムサーバーの  Kubernetes での運用について
Go 製リアルタイムサーバーの Kubernetes での運用について
 
Parallel Technology
Parallel TechnologyParallel Technology
Parallel Technology
 
Swiftによる関数型プログラミング超入門
Swiftによる関数型プログラミング超入門Swiftによる関数型プログラミング超入門
Swiftによる関数型プログラミング超入門
 
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
ASP.NET 新時代に向けて ~ ASP.NET 5 / Visual Studio 2015 基礎解説
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Next
 
Play勉強会 第3回
Play勉強会 第3回Play勉強会 第3回
Play勉強会 第3回
 

第一回社内 Scala 勉強会(一部抜粋)その 2

  • 1. Scala の言語機能 – 継承による実装  実装継承  実装のために行う継承(情報量増えてないゾ)  実装詳細を持つクラスを、利用したいクラスが継承  親クラスのように振る舞いたいわけではない! https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 2. Scala の言語機能 – 継承による実装  Java による素朴な例 public class Counter { private int counter; public void addCounter() { counter++; } public int getCounter() { return counter; } } public class VisitorsCounter extends Counter { public void visit() { addCounter(); } public int getVisitorsNum() { return getCounter(); } } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 3. Scala の言語機能 – 継承による実装  Java による素朴な例  問題点 1:実装詳細が外部に公開されてしまう VisitorCounter visitorCounter = new VisitorCounter(); visitorCounter.visit(); visitorCounter.addCounter(); // oops! https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 4. Scala の言語機能 – 継承による実装  Java による素朴な例  問題点 1:実装詳細が外部に公開されてしまう  問題点 2:意図しない polymorphism  Counter のように振る舞いたいわけではない Counter counter = new Counter(); // ok counter = new VisitorCounter(); // oops! https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 5. Scala の言語機能 – 継承による実装  Java による素朴な例  問題点 1:実装詳細が外部に公開されてしまう  問題点 2:意図しない polymorphism  問題点 3:複数の実装詳細を同時に扱えない  Java は単一継承のみ、多重継承はない public class Timer { … } public class Counter { … } public class VisitorCounter extends ??? // さてはて… https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 6. Scala の言語機能 – 継承による実装  C++ の private/protected 継承 class Counter { int counter_ = 0; // C++11 の member initialization public: void add() { counter_++; } int get_counter() const { return counter_; } }; class VisitorsCounter : private Counter { public: void visit() { add(); } int get_visitors_num() const { return get_counter(); } }; https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 7. Scala の言語機能 – 継承による実装  C++ の private/protected 継承  実装詳細は外部に公開されない  意図しない polymorphism は発生しない VisitorCounter* visitor_counter = new VisitorCounter(); visitor_counter->visit(); // visitor_counter->add(); // error! // Counter* counter = visitor_counter; // error! https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 8. Scala の言語機能 – 継承による実装  C++ の private/protected 継承  実装詳細は外部に公開されない  意図しない polymorphism は発生しない  複数の実装詳細を扱える…が、取扱注意 https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 9. Scala の言語機能 – 継承による実装  C++ の private/protected 継承  問題点:too complex!!!  解決:Java と同様、所有(composition)を利用する  C++ の良いところは、良く考えられていることであり  C++ の悪いところは、良く考えられ過ぎていることである  詠み人知らず https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 10. Scala の言語機能 – 継承による実装  実装継承、よりも…  一般的には所有(composition)が望ましい  問題点 1:書くのが面倒… public class Foo { private ImplA implA; private ImplB implB; public Foo() { implA = new ImplA(); implB = new ImplB(); } public void implementedByA() { implA.something(); } public void implementedByB() { implB.something(); } public void implementedByAandB() { implA.something(); implB.something(); } } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 11. Scala の言語機能 – 継承による実装  実装継承、よりも…  一般的には所有(composition)が望ましい  問題点 1:書くのが面倒…  問題点 2:実装詳細がカスタマイザブルでない  解決: Dependency Injection(DI)  問題点:書くのが面倒…(二度目)  解決: DI Container  問題点 1: 書くのが面倒(三度目)だし仰々しすぎ  問題点 2: Java 以外であまり流行ってない  結論: Java ダメだこれ https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 12. Scala の言語機能 – 継承による実装  他の言語  Eiffel とか Python とか Common Lisp(CLOS) とか  色々な言語毎に、解決方法と問題点がある  このプレゼンはそれを書くにはなんかが少なすぎる  そもそもオブジェクト指向と呼ばれる物が多すぎる!  まとめたら論文にできそう  なんならもうありそう https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 13. Scala の言語機能 – 継承による実装  Scala の self type annotations と trait/mixin trait Counter { private var c: Int = 0 def add() { c += 1 } def get: Int = c } class VisitorsCounter { self: Counter => def visit() { add() } def getVisitors = get } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 14. Scala の言語機能 – 継承による実装  Scala の self type annotations と trait/mixin  trait/mixin とは…?  trait はざっくりいうと実装を持てる Java の interface  abstract class ではないので、複数の trait を継承可能  trait の継承を mixin と呼んだりする trait Counter { private var c: Int = 0 def add() { c += 1 } def get: Int = c } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 15. Scala の言語機能 – 継承による実装  Scala の self type annotation と trait/mixin  self type annotation とは…?  その型の具象的な値に対する型注釈  VisitorsCounter は Counter を継承しなければならない class VisitorsCounter { self: Counter => // this class is `implemented by` Counter! def visit() { add() } def getVisitors = get } // val counter = new VisitorsCounter // error! https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 16. Scala の言語機能 – 継承による実装  Scala の self type annotation と trait/mixin  お節介な型推論に御用心  型推論の方でもちょろっと触れます val counter = new VisitorsCounter with Counter // mixin! ok! …? counter.add() // oops! why is this valid? // counter type is “VisitorsCounter with Counter” // we should annotate type explicitly! val annotated: VisitorsCounter = new VisitorsCounter with Counter // ok! // annotated.add() // error! annotated.visit() https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 17. Scala の言語機能 – 継承による実装  Scala の self type annotation と trait/mixin  複数の class を指定することも可能  正確には高々一つの class と任意個の trait  より正確には class linearization の結(省略されました) class VisitorsCounter { self: Counter with Timer => … } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 18. Scala の言語機能 – 継承による実装  Scala の self type annotation と trait/mixin  とか不要で interface extraction でいいんじゃ?  Java でも解決だよね? trait VisitorsCounter { … } trait Counter { … } trait Timer { … } class VisitorsCounterImpl extends VisitorsCounter with Counter with Timer { … } val counter: VisitorCounter = new VisitorsCounterImpl https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 19. Scala の言語機能 – 継承による実装  Scala の self type annotation と trait/mixin  とか不要で interface extraction でいいんじゃ?  問題点:実装詳細が変わるたびにコードの重複が発生 trait PreciseTimer extends Timer { … } class VisitorsCounterImpl extends VisitorsCounter with Counter with Timer { … // implementation } class PreciseVisitorsCounterImpl extends VisitorsCounter with Counter with PreciseTimer { … // code duplication! } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 20. Scala の言語機能 – 継承による実装  Scala の self type annotation と trait/mixin  trait/mixin なら実装詳細を簡単に変更可能  コードの重複は発生しない class VisitorsCounter { self: Counter with Timer => … } trait PreciseTimer extends Timer { … } class PreciseVisitorsCounter extends VisitorsCounter with Counter with PreciseTimer // no code duplication! https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 21. Scala の言語機能 – 継承による実装  Scala の self type annotation と trait/mixin  実装持ってるもの多重継承して問題ないの?  Class linearization により継承ツリーは linearize される  結果、多重継承のように見えていたものは単一継承になる abstract class AbsIterator { … } trait RichIterator extends AbsIterator { … } class StringIterator extends AbsIterator { … } class Iter extends StringIterator with RichIterator { … } // Iter の継承ツリーは以下のように linearize される // Iter -> RichIterator -> StringIterator -> AbsIterator https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 22. Scala の言語機能 – 継承による実装  Scala の self type annotation と trait/mixin  trait は強力な言語機能、他にも色々有用  リッチインターフェースの提供  stackable な open recursion の実現  abstract override なんてニッチなものも…  強力さ故の代償も  Separate Compiliation 的には困った機能  詳細は javap –c すれば分かります。手前味噌ですが参考 https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
  • 23. Scala の言語機能 – 継承による実装  まとめ  Scala では以下の機能により  self type annotation による implemented by の表明  trait/mixin による柔軟な実装の提供  設計意図が伝わり安く、使い安い設計が可能  Java ほど貧弱でなく、C++ ほど複雑でなく  他の言語機能と組み合わせればもっと良くなるよ! https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential