※当サイトの記事には、広告・プロモーションが含まれます。

Java言語セミナーを受講して 5章

Java言語セミナーを受講しての続きになります。

今回は、いよいよオブジェクト指向の話になります。

オブジェクト指向

オブジェクト指向を使うとどうなるかというと、 

  • 再利用可能な設計ができます。
  • 機能変更に強い設計ができます。
  • あるプログラムの変更が他のプログラムに影響しないようにします。
  • そのかわり短期的には工数はむしろ増えます。

プログラミングの世界では、Don't repeat yourselfDRY)という原則があるようです。

意味は、『同じことを繰り返すな』ということで、コードの重複を避けることを意識しようということらしいです。

では、コードの重複の問題点はどんなものかというと、

  • コードが増えます。
  • 読み手は、記述されたコードを何かの意図でコードを分けたと思い込み、比較のための時間を無駄にしてしまいます。
  • 矛盾する実装の可能性があります(例えば一方は例外をログするが他方はしないなど)。
  • 修正時の変更箇所が増えます。

ただし、DRYが常に正しいとは限らない場合もあるようです。

 詳しくは下記サイトへ

「DRY」はつねに正しいわけではない 重複と密結合のトレードオフ - モジログ

 

オブジェクト指向とは

では、そもそもオブジェクト指向って何なんでしょうか? 

オブジェクト指向(オブジェクトしこう)とは

オブジェクト同士の相互作用として、システムの振る舞いをとらえる考え方である。

複雑なシステム記述、巨大なライブラリ(特に部品間で緊密で複雑な相互関係を持つもの)の記述においては、オブジェクト指向の考え方は必須である。 

オブジェクト指向 - Wikipedia

ふむふむ・・・どういうことよ、wikipediaさん、何を仰りたいんですか?と思った人は私の仲間です。

オブジェクト指向については、喧喧囂囂 (けんけんがくがく)でwikipediaによると、

Eclipseを開発したDave Thomasや、オブジェクト指向という言葉の生みの親であるAlan Kay博士は、オブジェクト指向という言葉は失敗だったと語っている。

これは、本来オブジェクト指向が重視すべきは「オブジェクト」ではなく「メッセージング」であるにもかかわらず「メッセージング」がおろそかにされているためである。

特に言語の進歩において「オブジェクト」や「クラス」の側面ばかり強調される傾向にあり、Alan Kay博士は「Smalltalkが最高に好きという訳ではないが、他の言語に比べればマシである。」と述べている。 

と結構に辛辣なお言葉をお偉いさんが仰ってました。

  Erlangの開発者Joe Armstrongの言葉の翻訳は下記サイトへ 

Java - オブジェクト指向はクソか? - Qiita

その後のJoe Armstrongのオブジェクト指向に対する見解 - Qiita

どうも、「メッセージング」なるものがオブジェクト指向では重要らしいですね。

そして、どうにもオブジェクト指向の欠点はこれまでにもだいぶ議論されてきているようです。

そんな、オブジェクト指向についてメモしていきたいと思います。

 

オブジェクトとクラス

オブジェクト指向というからには、オブジェクトとがなければ始まりません。

オブジェクトは、クラスをインスタンス化することで生成されます。

クラスは、オブジェクトを抽象化し一般化したものということになるようです。

ORACLEによるクラスの説明では、

In the real world, you'll often find many individual objects all of the same kind.
There may be thousands of other bicycles in existence, all of the same make and model.
Each bicycle was built from the same set of blueprints and therefore contains the same components.
In object-oriented terms, we say that your bicycle is an instance of the class of objects known as bicycles.
A class is the blueprint from which individual objects are created. 

となっていて、直訳すると、

日常で頻繁に、同じ種類の個々のオブジェクトをたくさん目にするでしょう。例として、同じ種類で作られたモデルの自転車が何千台もあったとします。各々の自転車は、同じ図面で作られたので同じ構成要素を含んでいると言えるでしょう。オブジェクト指向に当てはめた場合、あなたの自転車は、自転車というオブジェクトのクラスのインスタンスと言えます。クラスは、個々のオブジェクトを作成するための図面です。

クラスは設計図、そのクラスを元に作られた(インスタンス化した)のがオブジェクトということみたいです。

クラスは、

  • プロパティ(変数)の集まり = データ構造(Fields)
  • メソッド(処理)= データ構造(Fields)を扱う処理

で構成されてます。 

ORACLEによるJavaのオブジェクトのイメージ図はこんな感じです。(What Is an Object?

f:id:ts0818:20160207000942g:plain

Fields(データ構造)の中にあるものがプロパティの集まりで、Methodsのbehavior(ふるまい)によってプロパティに何か処理が実行されるとFields(データ構造)のstate(状態)が変わっていく、ということはオブジェクト全体としても変化が起こる、それを複数のオブジェクト同士で行っていくことがオブジェクト指向ということらしいです。

開発では様々なクラスを使っていくと思われるのですが、クラスを世界に一つだけの花たらしめてるもの(クラス同士を差別化してるもの)が、Feilds(データ構造)の違いということらしいです。

例えば、クラスA、クラスB、クラスCが存在した場合、それぞれをFields(データ構造)の違いで区別するということみたいです。

 

実際にクラス(設計図)を作成

クラスを作ってみます。(ORACLEのクラス見本のソースコードを使わせてもらいました。) 

class Bicycle {
//プロパティ
    int cadence = 0; //1分間のクランク回転数 = ペダルを回す速さ
    int speed = 0;   //スピード
    int gear = 1;    //ギア
//cadenceプロパティを変化させるメソッド
    void changeCadence(int newValue) {
         cadence = newValue;
    }
//gearプロパティを変化させるメソッド
    void changeGear(int newValue) {
         gear = newValue;
    }
//speedプロパティを変化させる(速度上げる)メソッド
    void speedUp(int increment) {
         speed = speed + increment;   
    }
//speedプロパティを変化させる(速度下げる)メソッド
    void applyBrakes(int decrement) {
         speed = speed - decrement;
    }
//表示するメソッド
    void printStates() {
         System.out.println("cadence:" +
             cadence + " speed:" + 
             speed + " gear:" + gear);
    }
}

 

オブジェクトを生成するためのクラスを作成

オブジェクトはクラスを元に作られますが、オブジェクトを生成するためのクラスを作る必要があります。今回は1つのファイルにBicycleクラスとBicycleDemoクラスを記述しています。

オブジェクトを作成するにはnewキーワードを使います。 

データ型(クラス型) 参照変数名 = new クラス名();

sample_test16.javaの続きに記述

class BicycleDemo {
    public static void main(String[] args) {

// 2つの異なるオブジェクトを生成 
// Bicycleクラスのオブジェクトを参照変数bike1、bike2に格納
        Bicycle bike1 = new Bicycle();
        Bicycle bike2 = new Bicycle();

// 参照変数名.メソッドでBicycleクラスのメソッドを実行 
// bike1のオブジェクト
        bike1.changeCadence(50);
        bike1.speedUp(10);
        bike1.changeGear(2);
        bike1.printStates();
        
// bike2のオブジェクト
        bike2.changeCadence(50);
        bike2.speedUp(10);
        bike2.changeGear(2);
        bike2.changeCadence(40);
        bike2.speedUp(10);
        bike2.changeGear(3);
        bike2.printStates();
    }
}    

同じBicycleクラスから、いくつものオブジェクトを作ることができるのですが、複数作られたオブジェクトは最初は全部new Bicycle( ); でできてるので区別がつかない訳です。

インスタンス化のイメージ図

f:id:ts0818:20160207234950p:plain

 そこで、参照変数というものでメモリ上のオブジェクトの場所を示すことで区別をつけているようです。

参照のイメージ図

f:id:ts0818:20160208000425p:plain

オブジェクトに対してメソッドを呼び出すには、

参照変数.メソッド;    

と記述してるため、オブジェクトごとにプロパティの値を変えられ、Fields(データ構造)に変化をつけ各々のオブジェクトに違いをつけているようです。

 

ここまでの内容も下記書籍を参考にさせてもらっています。

ラクル認定資格教科書 Javaプログラマ Bronze SE 7/8 単行本(ソフトカバー) – 2015/10/10

f:id:ts0818:20160202070628j:plain

次回も、Java言語セミナーを受講してシリーズでいきたいと思います。

興味のある方はひき続き読んでみてやってください。 

今回はこのへんで。