JavaにおけるOOPS(オブジェクト指向プログラミング)のコンセプトについて – OOPSコンセプトの例
オブジェクト指向プログラミングの概念は、プログラミングにとって非常に重要です。OOPSの概念についての理解がなければ、オブジェクト指向プログラミングモデルでシステムを設計することはできません。
オブジェクト指向プログラミングモデルとは何ですか?
オブジェクト指向プログラミングのモデルは、オブジェクトという概念を中心に展開されています。オブジェクトとは何でしょうか?オブジェクトとは、クラスのインスタンスです。プロパティや関数を持っています。実世界のオブジェクトのようなものです。例えば、あなたの車や家、ノートパソコンなどがオブジェクトです。それらは特定のプロパティやメソッドを持ち、あるアクションを実行することができます。では、クラスとは何でしょうか?クラスはオブジェクトの設計図を定義します。オブジェクトのプロパティや機能を定義します。例えば、ノートパソコンはクラスであり、あなたのノートパソコンはそれのインスタンスです。
オブジェクト指向プログラミング概念
-
- 抽象化
-
- カプセル化
-
- ポリモーフィズム
-
- 継承
-
- 関連付け
-
- 集約(アグリゲーション)
- 合成 (コンポジション)
これらのオブジェクト指向プログラミングの概念を一つずつ見てみましょう。Javaプログラミング言語を使用してコードの例を示すので、JavaでOOPの概念をどのように実装するかを知ることができます。
1. 抽象化 (ちゅうしょうか)
抽象化(ちゅうしょうか)とは、内部の詳細を隠し、単純な形で物事を表現する概念です。例えば、2つの整数を足すメソッドです。このメソッドの内部処理は外部の世界から隠されています。オブジェクト指向プログラミングにおいては、カプセル化や継承など、多くの方法で抽象化を実現することができます。Javaプログラムも抽象化の素晴らしい例です。ここではJavaが簡単な文を機械語に変換し、内部の実装の詳細を外部の世界から隠しています。
詳読:OOPSにおける抽象とは何ですか?
2. カプセル化 (Kapuserekka)
カプセル化は、オブジェクト指向プログラミングにおける抽象化を実装するための技術です。カプセル化は、クラスのメンバーやメソッドへのアクセス制限に使用されます。アクセス修飾子のキーワードは、オブジェクト指向プログラミングにおけるカプセル化に使用されます。たとえば、Javaでは、private、protected、publicのキーワードを使用してカプセル化が実現されます。
3. 多様性 (たようせい)
ポリモーフィズムは、オブジェクトが異なる状況で異なる振る舞いをする概念です。ポリモーフィズムには、コンパイル時ポリモーフィズムと実行時ポリモーフィズムの2つのタイプがあります。コンパイル時ポリモーフィズムは、メソッドのオーバーロードによって実現されます。以下のようなクラスを持つことができます。
public class Circle {
public void draw(){
System.out.println("Drwaing circle with default color Black and diameter 1 cm.");
}
public void draw(int diameter){
System.out.println("Drwaing circle with default color Black and diameter"+diameter+" cm.");
}
public void draw(int diameter, String color){
System.out.println("Drwaing circle with color"+color+" and diameter"+diameter+" cm.");
}
}
ここでは、複数の描画メソッドが存在しますが、それらの動作は異なります。これはメソッドのオーバーローディングのケースであり、全てのメソッドの名前が同じで引数が異なるためです。コンパイラはコンパイル時に呼び出すメソッドを識別することができますので、これはコンパイル時のポリモーフィズムと呼ばれています。ランタイムのポリモーフィズムは、オブジェクト間に「IS-A」の関係がある場合に実装されます。これは、サブクラスがスーパークラスのメソッドをランタイムのポリモーフィズムのためにオーバーライドすることとも呼ばれます。スーパークラスを基準に作業している場合、実際の実装クラスはランタイムで決定されます。コンパイラはどのクラスのメソッドが呼び出されるかを決定することができません。この決定はランタイムで行われるため、ランタイムのポリモーフィズムまたは動的なメソッドディスパッチという名前です。
package com.scdev.test;
public interface Shape {
public void draw();
}
package com.scdev.test;
public class Circle implements Shape{
@Override
public void draw(){
System.out.println("Drwaing circle");
}
}
package com.scdev.test;
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Drawing Square");
}
}
形はスーパークラスであり、サブクラスには円と正方形があります。以下にランタイムのポリモーフィズムの例があります。
Shape sh = new Circle();
sh.draw();
Shape sh1 = getShape(); //some third party logic to determine shape
sh1.draw();
上記の例では、Javaコンパイラは実行時に使用されるShapeの実際の実装クラスを知りません。したがって、ランタイムのポリモーフィズムが発生します。
4. 相続 (Sōzoku)
継承とは、オブジェクト指向プログラミングの概念の一つで、あるオブジェクトが別のオブジェクトを基にして生成されることを指します。継承はコードの再利用の仕組みです。継承されるオブジェクトはスーパークラスと呼ばれ、スーパークラスを継承するオブジェクトはサブクラスと呼ばれます。Javaでは、extendsキーワードを使用して継承を実装します。以下はJavaにおける継承の単純な例です。
package com.scdev.java.examples1;
class SuperClassA {
public void foo(){
System.out.println("SuperClassA");
}
}
class SubClassB extends SuperClassA{
public void bar(){
System.out.println("SubClassB");
}
}
public class Test {
public static void main(String args[]){
SubClassB a = new SubClassB();
a.foo();
a.bar();
}
}
5. 協会 (きょうかい)
関連付けは、オブジェクト間の関係を定義するためのオブジェクト指向プログラミング(OOPS)の概念です。関連付けはオブジェクト間の多重度を定義します。例えば、教師オブジェクトと学生オブジェクトの関係は一対多の関係です。同様に、学生オブジェクトも教師オブジェクトとの一対多の関係を持つことがあります。しかし、学生オブジェクトと教師オブジェクトはお互いに独立しています。
集計
集約は特別な関連の一種です。集約では、オブジェクトには独自のライフサイクルがありますが、所有関係も存在します。オブジェクト間に「持っている」という関係や所有関係がある場合、それは集約のケースです。
6. 作文
作成
構成は、集約の特殊なケースです。構成は、より制約のある集約の形式です。”HAS-A”の関係で含まれるオブジェクトが単独で存在できない場合、それは構成のケースです。たとえば、家は部屋を持っています。ここで、部屋は家なしでは存在できません。構成は、継承よりも優れていると言われています。Composition vs Inheritanceで詳しく読むことができます。
さらに読むこと: Javaにおけるコンポジション
OOPSの概念についての簡単なまとめについては以上です。
弊社のGitHubリポジトリから、さらに多くのJavaのサンプルプログラムを参照できます。
参考文献: https://docs.oracle.com/javase/tutorial/java/concepts/
(以下の情報は、上記URLにあるJavaの概念のチュートリアルを参考にしました。)