オブジェクト指向(Java)について

はじめに

システム開発にJavaが広く採用されている理由の1つに、Java言語がオブジェク指向言語であることが挙げられます。Java言語を理解するための基礎知識として、オブジェクト指向に関する重要なポイントを抜粋して掲載しています。

コンセプト

  1. システム開発における課題

    1. 開発期間の短縮
    2. システムの仕様変更に伴うコストの削
  2. システム開発における実現すべきとされていること
    1. 以前に作成したプログラムを再利用する
    2. 大勢のエンジニアで共同開発を行う
    3. プログラムの変更箇所をいち早く特定し対応する
    4. あるプログラムの変更が他のプログラムに影響しないようにす
  3. オブジェクトとは、役割に応じて分割された単位
  4. オブジェクトの情報(状態)を表現するものが属性であり、機能を表現するものが操作(サービス)である
  5. オブジェクトは属性と操作(サービス)を一体化することで表現される。これはカプセル化と呼ぶ
  6. カプセル化のメリット
    1. オブジェクトの内部構造を知る必要がない
    2. 属性値の変更は操作経由の制限である
    3. 操作名が同じなら、内部構造が変わっても利用する側にそれを意識させない
    4. 属性に不整合な値が入らないよう、操作でチェックできる
  7. カプセル化により、属性を外部から保護するデータ隠蔽を実現できる
  8. オブジェクト同士は、互いに要求を出し、連携し動作する
    ※オブジェクトとオブジェクトを互いに連携させる、つまりオブジェクト同士の関係を考えることで、 システムを構築していきます
  9. Java言語では、属性は変数として扱い、操作(サービス)はメソッドとして扱う

クラス定義とオブジェクの生成・使用

  1. クラスは、オブジェクトを作成するための土台となる雛形である
  2. インスタンス化は、あるクラスをもとにして、実際に使うことができる「モノ」にすることである
  3. Java言語では、クラスの直下に用意された変数やメソッドを総称してメンバと呼ぶ
  4. Java言語では、ソースファイルにクラスを定義しコンパイルすると、定義したクラス名が使用されたクラスファイル(.classファイル)が生成される
  5. Java言語では、必ず1つ以上のクラスを定義する
  6. Java言語では、クラス定義
    [アクセス修飾子] [static] [final] class クラス名 { 
    	[アクセス修飾子] [static] [final] データ型 メンバ変数名;
    
    	/* デフォルトコンストラクタ */
    	[アクセス修飾子] [static] [final] コンストラクタ名() {}
    	/* 引数ありのコンストラクタ */
    	[アクセス修飾子] [static] [final] コンストラクタ名(引数リスト) {}
    
    	[アクセス修飾子] [static] [final] データ型 メソッド名(引数リスト) {}
    }
    
    ※アクセス修飾子:public/protected/デフォルト(指定なし)/private
    
  7. コンストラクタは、インスタンス化のときに最初に呼び出されるブロックを定義するものである
  8. コンストラクタは、名前がクラス名と同じであり、戻り値はもたない。voidも指定しない
  9. クラスで明示的にコンストラクタを定義しなかった場合、コンパイルのタイミングでデフォルトコンストラクタが追加される
  10. クラスで明示的にコンストラクタを定義している場合、デフォルトコンストラクタは追加されない
  11. オブジェクトの属性であるメンバ変数に格納される値はオブジェクトごとに異なる
  12. インスタンス化にはnewキーワードを使用する
    データ型 変数名 = new コンストラクタ名();
  13. メンバには、インスタンスメンバとstaticメンバの2種類がある
    メンバ変数 メンバメソッド
    インスタンスメンバ インスタンス変数
    (非static変数)
    インスタンスメソッド
    (非staticメソッド)
    staticメンバ static変数 Staticメソッド
  14. インスタンスメンバは、そのクラスをインスタス化すると、各オブジェクトの中に個々の領域として確保される
  15. オブジェクトに対してメンバの呼び出しはインスタンス化した際の変数名を使用する
    変数名.メンバ変数名;
    変数名.メンバメソッド名();
    
  16. staticメンバは複数インスタンス化されても1箇所で領域が確保される
  17. staticメンバを他クラスから呼び出す構文は、以下のとおりである
    クラス名.static変数名;
    クラス名.staticメソッド名();
    

    なお、以下の呼び出しも可能である

    データ型 変数名 = new コンストラクタ名();
    変数名. static変数名;
    変数名. staticメソッド名();
    

三大特徴(カプセル化、継承、多態性)

  1. カプセル化は、オブジェクトの属性と操作を一体化することで表現されることである。
    カプセル化(隠ぺい)は、アクセス修飾子を使い、 オブジェクトの持つ任意のメンバを隠ぺいすること。
    ・アクセス修飾子とは、public、protected、デフォルト(指定なし)、privateといった修飾子の総称で、クラスやそのメンバがどこからアクセス可能であるかを決定します

    アクセス修飾子 概要
    public すべてのクラスからアクセスできる
    protected 現在のクラスとサブクラスからアクセスできる
    デフォルト(指定なし) 現在のクラスと同じパッケージのクラスからアクセスできる
    private 現在のクラスからだけアクセスできる

    ※具体的な状況は下図のとおりである

    ・アクセス修飾子は、クラス、コンストラクタ、メンバ変数、メンバメソッドに対し、他のクラスへのアクセス公開を制御するものである

    アクセス修飾子 適用場所
    クラス コンストラクタ メンバ変数 メンバメソッド
    public
    protected ×
    デフォルト
    (指定なし)
    private ×

    ・アクセス修飾子は、クラス、コンストラクタ、メンバ変数、メンバメソッドに対し、他のクラスへのアクセス公開を制御するものである

    データ隠蔽を実現するためにアクセス制御の推奨ルールは以下のとおりである
    (ア)インスタンス変数は、アクセス修飾子をprivateにする
    (イ)メソッドは、一般的にアクセス修飾子をpublicにする

  2. 継承(インヘリタンス)

    継承は、すでに定義してあるクラスを拡張して、新しいクラスを定義することである。

    スーパークラスは継承のもととなるクラス、サブクラスはそれを拡張して新しく作成したクラスである

    ・サブクラスでは独自にもつ属性、操作のみを定義する

    ・サブクラスをインスタンス化するとスーパークラスの情報を引き継いだオブジェクトが生成される

    インタフェースは、オブジェクトを利用する側に公開すべき操作をまとめたクラスの仕様のことである

    ・Java言語は単一継承のみサポートしているため、extendsキーワードの後に指定できるクラスは1つだけである

    ・サブクラスを定義する際には、extendsキーワードを使用する

    [アクセス修飾子] [static] [final] class サブクラス名 extends スーパークラス名 { }

    ・extendsキーワードを使用しなかった場合、コンパイルによってjava.lang.Objectクラスを継承するクラスとしてクラスファイルが作成される

    ・オーバーロードとは、クラス内に同じ名前のメソッドやコンストラクタを複数定義すること

    ・オーバーロードはメソッド名(もしくはコンストラクタ名)が同じであり、引数の並び、型、数が異なっていることが条件である

    ・オーバーライドは、スーパークラスで定義されたメソッドをサブクラスで再定義することである。ルールは以下のとおりである

    (ア)メソッド名、引数リストがまったく同じメソッドをサブクラスで再定義する;

    (イ)戻り値はスーパークラスと同じものか、もしくはその戻り値に継承関係がありサブクラスであれば使用可能;

    (ウ)アクセス修飾子は、スーパークラスと同じものか、それよりも公開範囲が広いものであれば使用可能;

    ・final修飾子はクラス、変数、メソッドに適用できる

    (ア)変数につけた場合は、定数になる

    (イ)メソッドにつけた場合は、サブクラス側でそのメソッドをオーバーライドできなくなる

    (ウ)クラスにつけた場合は、そのクラスをもとにサブクラスを定義できなくなる

    ・this修飾子は自分自身(自オブジェクト)を表す

    (ア)インスタンス変数への適用:this.変数名

    (イ)コンストラクタ呼び出しへの適用:this()

    ※this()はコンストラクタ定義の先頭に記述する

    ・superは、自オブジェクトから見てスーパークラスのオブジェクトを表す

    (ア)メソッド呼び出しの適用:super.メソッド名()

    (イ)コンストラクタ呼び出しへの適用:super()

    ・クラスのインスタンス化は、必ずスーパークラスのコンストラクタが実行されてからサブクラスのコンストラクタが実行される

    ・サブクラス内のコンストラクタ定義内に明示的なsuperによるコンストラクタ呼び出しがないと、コンパイルのタイミングでsuper()が追加される

  3. 多態性(ポリモーフィズム)

    多態性(ポリモーフィズム、多相性)は、共通のインタフェースを持つ操作でも、実際にはオブジェクトごとに振る舞いや動作が異なることである

    ・具象クラスは、インスタンス化ができるクラス

    ・抽象クラス(abstractクラス)の構文と特徴は以下のとおりである

    [アクセス修飾子] abstract class クラス名 { 
    	[アクセス修飾子] データ型 具象メソッド名(引数リスト) {}
    	[アクセス修飾子] abstract 戻り値の型 抽象メソッド名(引数リスト);
    }
    

    (ア)クラス宣言でabstractキーワードを指定する

    (イ)処理内容が記述された具象メソッドと抽象メソッドを混在させることができる

    (ウ)インスタンス化はできず、利用する場合はサブクラスを定義する。サブクラス側では抽象メソッドをオーバーライドする

    (エ)抽象クラスをもとにサブクラスを定義する場合はextendsキーワードを使用する

    ・抽象メソッド(abstractメソッド)の構文と特徴は以下のとおりである

    [アクセス修飾子] abstract 戻り値の型 抽象メソッド名(引数リスト);

    (ア)メソッド宣言でabstractキーワードを指定する

    (イ)修飾子、戻り値、メソッド名、引数リストは、通常のメソッドと同様に記述する

    (ウ)処理をもたないため、メソッド名()の後に{}を記述せず、「;」(セミコロン)で終わる

    ・インタフェースの構文と特徴は以下のとおりである

    [アクセス修飾子] interface インタフェース名 { }

    (ア)インタフェース宣言にはinterfaceキーワードを指定する

    (イ)変数は、定数しか定義できない

    (ウ)インスタンス化はできず、使用する場合は実装クラスを定義する。実装クラス側では抽象メソッドをすべてオーバーライドする

    (エ)実装クラスを定義するにはimplementsキーワードを使用する

    (オ)インスタンスをもとにサブインタフェースを宣言する場合はextendsキーワードを使用する

    ・インタフェース内で変数を宣言すると、暗黙的にpublic static final修飾子が付与されるため、staticな定数となる

    ・インタフェース内でメソッドを宣言すると、暗黙的にpublic abstract修飾子が付与される

    ・実装クラスにおいて、implementsの後に、1つ以上のインスタンスを複数指定できる

    ・実装クラスが具象クラスの場合、implementsで指定したインタフェースのすべてのメソッドをオーバーライドする。また、オーバーライトする際には、public修飾子をつける

    ・あるクラスにおいて、implementsとextendsを併用する際は、extendsを先に記述する

    ・インタフェースを継承した、サブインタフェースを作成するにはextendsを使用する。なお、インタフェースを複数のインタフェースを継承(extends)することが可能である

    ・基本データ型について、暗黙の型変換のルールは以下のとおり

    byte → short → int → long → float → double
                  char

    ・参照型について、暗黙の型変換のルールは以下のとおり:

    (ア)サブクラス → スーパークラス

    (イ)実装クラス → インスタンス

    ・基本データ型、参照型ともにキャストによる型変換をするには、()キャスト演算子を使用する

    (目的型)値

    ・サブクラス(もしくは実装クラス)のオブジェクトは、スーパークラスクラス(もしくはインスタンス)の型で宣言された変数で扱うことができる。その際、メソッドがオーバーライドされていると、サブクラス(もしくは実装クラス)で定義されたメソッドが優先して呼び出される

    ・コンパイル時には、呼び出そうとしているメソッドが宣言されているクラスに定義されているかどうかチェックする

    ・実行時には、インスタンス化されているオブジェクトのメソッドが呼び出される

Smallitのサービス