オブジェクト指向プログラミングの【3大要素】について解説

スポンサーリンク

こんにちは!しーま(@s59shima)です。

いつもブログをご覧いただきありがとうございます。

今回は、こんな悩みや疑問のある方に向け記事を書きました。

プログラミング学習中
プログラミング学習中

オブジェクト指向」って言葉をプログラミング学習中によく聞くけど、正直、あまり理解していないかも。そもそも、3大要素って何だっけ!?

オブジェクト指向についてもっと知りたい方3大要素の特徴やメリットについて知りたい方おすすめです。

Java経験者
Java経験者

現在、人気の高いプログラミングの大半はオブジェクト指向プログラミング言語です。どのくらい重要なのか下記の図を参考にしてみましょう!

TIOBEが公開した2020年1月時点のプログラミング言語別人気ランキングです。

2020年1月のプログラミング言語ランキング

出典 :2020年1月のTIOBEインデックス( https://www.tiobe.com/tiobe-index/ )

2位のC言語以外は全てオブジェクト指向プログラミング言語となっていることがわかります。

順位プログラミング言語パラダイム
1Javaオブジェクト指向
2C手続き型
3Pythonオブジェクト指向
4C++オブジェクト指向
5C#オブジェクト指向

この結果からオブジェクト指向プログラミングは押さえておきたいところですよね。

≪スキマ時間、活用してみませんか≫

世界最大級のオンライン学習サイトUdemy

オブジェクト指向とは

オブジェクト指向を学ぶには、まず、【オブジェクト】と【クラス】の2つをおさえる必要があります。オブジェクトとは、プログラミング世界ではモノ(物)に例えられます。そして、クラスとは、データ(属性)振る舞い(メソッド)を定義したものとイメージすると分かりやすいと思います。

3大要素

3大要素(継承・ポリモーフィズム・カプセル化)について

以上が3大要素になります。この3大要素は主に大規模なシステム設計・開発する場合に効果を発揮します。

それでは1つ1つ説明します。

継承

【継承】について解説します。

継承とは

あるクラスの機能(フィールド, メソッド)を引き継いだクラスのこと

下記のように言われることが多いです。

引き継ぎ元のクラス:スーパークラス 又は 基底クラス

引き継ぎ先のクラス:サブクラス 又は 派生クラス

プログラミング学習中
プログラミング学習中

どんなメリットがあるの!?

Java経験者
Java経験者

継承の活用によって、コード重複クラス再利用性を高めてくれます。

Javaで継承を使用する場合、「extends」というキーワードを使用します。

それでは、実際にサンプルコードを見ていきましょう。

スーパークラスをEmployee(社員)クラスとし、それを継承したサブクラスEngineer(エンジニア)クラスを作成していきます。

package test;

public class Employee {
	String name;
	int age;
	void work() {
		System.out.println("name:" + name);
		System.out.println("age:" + age);
	}
}

Employee(社員)クラスは、name(名前)、age(年齢)という2つの変数と、workという文字列を出力するメソッドを定義したクラスになります。

package test;

public class Engineer extends Employee {

	public static void main ( String[] args ) {

		Engineer enginner = new Engineer();
		enginner.name = "sample user";
		enginner.age = 30;
		enginner.work();
	}
}

Employee(社員)クラスを継承したEngineer(エンジニア)クラスを見てみます。自クラスでは変数の定義を行っていませんが、name / age に値を代入し、workメソッドも使用できることが分かります。

Engineer(エンジニア)クラスを出力した結果を以下に示します。

> name:sample user
> age:30

注意点

注意点が2つあります。下記の2つは構文エラーになってしまいますので注意が必要です。

  • 継承するクラスは1つ
  • アクセス修飾子finalが付いていないこと
継承するクラスは1つ

例)継承するクラスを2つ定義した場合

package test;

public class Engineer extends Employee, Position {

	public static void main ( String[] args ) {

		Engineer enginner = new Engineer();
		enginner.setName("sample user");
		enginner.setAge(30);
		enginner.work();
	}
}

Employee(社員)クラスとPosition(役職)クラスの両方を継承しようとしていますが、継承できるクラスは1つなので、構文エラーとなってしまいます。

アクセス修飾子finalが付いていないこと

例)アクセス修飾子finalを付与したクラスを継承した場合

pablic class Employee → final class Employee

Employee(社員)クラスのアクセス修飾子を【pablic】から【final】に変更した場合、Engineer(エンジニア)クラスで構文エラーが発生します。

↓ 継承について詳しく解説した記事があります。合わせてどうぞ ↓

カプセル化

Java経験者
Java経験者

次は、カプセル化について見ていきましょう!

カプセル化は、ソフトウェア設計において重要な設計原則の1つです。

カプセル化の特徴

関係するデータをまとめ かつ そのデータを使う処理もまとめる。

↓↓↓

フィールドに対して好き勝手に操作されるのを防ぎ、データ隠ぺいを実現。

カプセル化を実現するために、以下のように形にします。

  • フィールドには【private】アクセス修飾子を付与。
  • フィールドの値を利用したい場合、アクセサメソッド(get~ / set~)を使用。

それでは、カプセル化を実現したサンプルコードを見ていきましょう。

さきほど、使用した親クラスのEmployee(社員)クラスを少し書き換えてみます。

package test;

public class Employee {
	private String name;
	private int age;
	void work() {
		System.out.println("name:" + getName());
		System.out.println("age:" + getAge());
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

name, ageフィールドに対してprivateアクセス修飾子を付けました。

継承したクラスからフィールドの値を参照できるようにメソッドを追加しています。

Engineer(エンジニア)クラスも少し書き換える必要があるため、変更します。

package test;

public class Engineer extends Employee {

	public static void main ( String[] args ) {
		Engineer enginner = new Engineer();
		enginner.setName("sample user");
		enginner.setAge(30);
		enginner.work();
	}
}

name, ageフィールドを参照する際は、setメソッドを使用します。

ここで少し注意が必要なのは、フィールドに対してsetメソッドを使用して値を無条件に変更しています。

これだとカプセル化にする前と変わらないですよね。

そのため、setメソッド内の処理については考慮が必要になります。

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

三大要素のポリモーフィズム
Java経験者
Java経験者

最後に、ポリモーフィズムについて見ていきましょう!

同じメソッドを記述しても、異なる動作を実現できること。

この特徴をおさえつつ、「オーバーロード」「オーバーライド」について解説します。

オーバーロード(多重定義)

Employee(社員)クラスに引数ありのworkメソッドを追加しました。同じメソッド名が2つあるのに注目してください。引数の型や引数の数が異なれば更にメソッドを追加することができます。

package test;

public class Employee {
	private String name;
	private int age;
	void work () {
		System.out.println("name:" + getName());
		System.out.println("age:" + getAge());
	}
	void work ( String keyword ) {
		System.out.println( keyword );
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

Engineer(エンジニア)クラスでも、workメソッドを2つ(引数なし / あり)を定義することができます。

package test;

public class Engineer extends Employee {

	public static void main ( String[] args ) {

		Engineer enginner = new Engineer();
		enginner.setName("sample user");
		enginner.setAge(30);
		enginner.work();
		enginner.work( "overload" );
	}
}

オーバーライド(再定義)

オーバーライドには、以下3つのルールがあります。

  • シグニチャ(型・数・順番)が同じであること
  • 戻り値が同じ型 又は サブクラス型であること
  • アクセス修飾子は同じか、より緩い修飾子であること
package test;

public class Engineer extends Employee {

	void work () {
		System.out.println( "Enginner" );
	}
	public static void main ( String[] args ) {

		Engineer enginner = new Engineer();
		enginner.setName("sample user");
		enginner.setAge(30);
		enginner.work();
	}
}

Engineer(エンジニア)クラスにEmployee(社員)クラスで定義しているworkメソッドを追加してみます。コンパイルエラーなどは発生せず、正常に【Enginner】と出力されることを確認できました。

まとめ

今回は、オブジェクト指向の3大要素について解説しました。

最後まで読んでいただきありがとうございました(*^-^*)

本記事をまとめると以下の通りです。

■継承

  • 共通になる部分を1つのクラスにまとめ、引き継ぐ仕組み

■カプセル化

  • 関係するデータ・処理をまとめ、データ隠ぺいを実現

■ポリモーフィズム

  • 同じメソッドを記述しても、異なる動作を実現

関連記事はこちら

人気記事はこちら

IT系フリーランス専門エージェントサービス第1位のMidWorksは業界トップクラスの低マージンで多くのエンジニアから選ばれています!!

Javaスキルで悩んでいる方必見!本気で学習できる環境を探してみよう!
詳細はこちら
Javaスキルで悩んでいる方必見!本気で学習できる環境を探してみよう!
詳細はこちら
タイトルとURLをコピーしました