ゆき社長

シーゲンガーのお勉強 ゲームプログラマ、ゲーマー、色々!

Java8

Java8をそろそろ勉強。

Java7は正直ほとんど見てないんだよね 6ぐらいで終わってる

でも8はJavaが大きくかわった一歩なので 調べるべき!

まず、ラムダが出来た。これは大きい

今までは interface classを 無名関数として newしてattachしていた

それは冗長なコードで処理速度も遅く、綺麗なコードではなかった

もちろん classのメンバ関数を作りattachも出来るが

immutableにするほうがベストで メンバ関数で渡すのは アンチパターン

それが、ラムダ式で指定できるのだから

何も問題ない

そして、関数ポインタ(関数オブジェクト)が存在せず

関数オブジェクトを表現するために classをnewするという

C言語にも劣る冗長でオーバーヘッドの多い仕様が改善され

FunctionInterfaceというものが出来たらしい

(細かい中身は追っていないが、これを作った目的考えると、関数オブジェクトのような オーバーヘッドの少ない作りになっているはずである)

既存の関数を関数インタフェースに渡せる。つまり関数ポインタが使えるといっても良い

そして 定義済みの関数インタフェースが提供されているが

これは完全なC#のオマージュであろう。

アイコン業界ではオマージュは晒し処刑対象らしいが

プログラムの世界では、いい方向に向かうなら歓迎だ

そして StreamAPI

C#LINQ式のオマージュ

こういういい部分は取り入れるべきだろう

LINQ式についてはパフォーマンスに問題があるという人もいるし

誤差範囲という人もいて、速度評価は難しいが

時代の流れや可読性を考えると

速度は誤差範囲内で積極的に使うべきだと思う

C++においては 今のところLINQ式は取り入れないと発表があるが

LINQライクなライブラリもあり

使ってみて評価しようと思う

そのたOptionalやらDataTimeやら

Java8は良くなったと思うが

やはり

ジェネリクスに関して

Object型を経由させる部分が

どうしてもネックになっていると思う

ジェネリクスさえ ちゃんと解決できれば

まだまだ現役言語になると思う

そして 一番危険視してたのが

interfaceのdefault実装

今までJavaという言語は、継承は単一継承しか許さず

interfaceのみ多重で継承させ

実装は単一継承というポリシーを守ってきた

もちろんこれには問題があり、interfaceを継承すると

何度もinterfaceの実装コードを書く必要があるという問題

なぜかJavaにはmixed-in がないため、中途半端と思っていた

今回は本当はJavaのポリシー変えたくないが

いろいろな理由からinterfaceにデフォルト実装をつけれるようになった

どう考えてもJava設計者としては つけたくなかった機能だと思うが・・

そして そのためにJavaでは多重継承が可能になった

そのため 多重継承につきもののダイヤモンド継承問題が発生した

ダイヤモンド継承は簡単にいえば多重継承することで、同じ親クラスが多重に存在し、どれを呼ぶかわからなくなる問題

C++では、多重の親クラスのメソッドを呼ぶ際に、スコープをつけて呼ぶことでかいけつさせているが

多重継承を許可するPythonではC3線形化アルゴリズムという

コンパイラが総合的に判断し、適した方のメソッドを呼ぶ事で解決させる

具体的には最も近い親を呼ぶ

それでも解決出来ない場合はJavaでは C++と同じく、オーバーライドしスコープを指定する

C++の多重継承と implementsによる多重継承の違いは

C++は本当に多重継承なので、インスタンス変数を持つため

状況は更にややこしいが

Javaの場合は interfaceはあくまでinterfaceで、インスタンスをもたない為

static finalでない変数は存在しないので問題ない

というところまで考えて 安心した。

結論で言うと Javaは多重継承ではなく mixed-inを採用したということ

やはり 未だ インスタンス変数まで持つ事のできる真の多重継承は人類にはまだ早い