1.事前知識
事前知識として、上記リンクの内容が必要です。
2.ポリモーフィズムとは
-
ポリモーフィズムとは、異なる処理を持つオブジェクトを、同一の操作で扱うことができることを指す。 -
操作している側は、オブジェクトの処理の違いを意識せずに操作を利用できる。 -
ポリモーフィズムは、多様性・多態性・多相性ともいう。 -
ポリモーフィズムは、抽象クラスを継承したサブクラスのインスタンスを抽象クラスの型で扱うことで実現している。
3.抽象クラスとは
-
抽象クラスとは、継承されることを前提に作られたクラスである。 -
抽象クラスは、インスタンス化できない特徴を持っている。 -
抽象クラスには、オーバーライドされることを前提とした「抽象メソッド」が定義できる。 -
抽象クラス、抽象メソッドには、「abstract修飾子」をつけて定義する。 -
抽象メソッドには、private/static/final修飾子を付けることはできない。 -
抽象クラスを利用するときは抽象クラスを継承したサブクラスを定義し、抽象メソッドをオーバーライドする。 -
抽象クラスを継承したクラスを具象クラスという。
4.ポリモーフィズムの基本的な書き方
テストクラス
package パッケージ名;
public class メインクラス名{
public static void main(String[] args) {
// インスタンスの生成
サブクラス名 変数名 = new サブクラス名();
// 処理の実行
変数名.抽象メソッド名(実引数)
}
}
抽象クラス
package パッケージ名;
abstract class 抽象クラス名{
// インスタンス変数の定義
private 型名 変数名;
// コンストラクタ(インスタンス生成時に実行される)
抽象クラス名(型名 引数){
初期化処理など
}
// 抽象メソッド
abstract 抽象メソッド名(型名 引数);
}
サブクラス
package パッケージ名;
class サブクラス名 extends 抽象クラス名{
// インスタンス変数の定義
private 型名 変数名;
// コンストラクタ(インスタンス生成時に実行される)
サブクラス名(型名 引数){
super(引数);
初期化処理など
}
// オーバーライド(抽象メソッド)
@Override
抽象メソッド名(型名 引数){
//処理
}
}
- 基本的な
ポリモーフィズムは上記のように記述します。
5.事前準備
- Eclipseを起動し、
[ファイル(F)]→[新規(N)]→[Java プロジェクト]を選択する。
- プロジェクト名に
Test1と入力し、完了ボタンをクリックする。
-
[ファイル(F)]→[新規(N)]→[クラス]を選択する。
- パッケージと名前に
Test1と入力し、完了ボタンをクリックする。
-
Test1.javaが作成されたことを確認する。
- 3と同様の手順でパッケージに
Test1、名前にGreetingと入力し、abstractにチェックを入れ、完了ボタンをクリックする。
- 3と同様の手順でパッケージに
Test1、名前にGoodMorning、スーパークラスにTest1.Greetingと入力し、完了ボタンをクリックする。
- 3と同様の手順でパッケージに
Test1、名前にHello、スーパークラスにTest1.Greetingと入力し、完了ボタンをクリックする。
- 3と同様の手順でパッケージに
Test1、名前にGoodEvening、スーパークラスにTest1.Greetingと入力し、完了ボタンをクリックする。
-
Test1.java、Greeting.java、GoodMorning.java、Hello.java、GoodEvening.javaが作成されれば成功。
6.記述例
Test1.java
package Test1;
public class Test1 {
public static void main(String[] args) {
// インスタンスの生成
Greeting[] greeting = {new GoodMorning("A"),new GoodMorning("B"),new GoodMorning("C")};
// 挨拶表示
for(int i = 0;i < greeting.length;i++) {
greeting[i].showGreeting();
}
}
}
Greeting.java
package Test1;
public abstract class Greeting {
// インスタンス変数
private String name;
// コンストラクタ
public Greeting(String name) {
this.name = name;
}
// getter
public String getName() {
return name;
}
// 挨拶の表示
abstract void showGreeting();
}
GoodMorning.java
package Test1;
public class GoodMorning extends Greeting {
// コンストラクタ
public GoodMorning(String name) {
super(name);
}
// 挨拶の表示
@Override
void showGreeting() {
System.out.println(getName()+"さん、おはようございます。");
}
}
- 上記の文をコピーして、文字コードは
S-JISを指定し、ファイル名をTest1.java,Greeting.java,GoodMorning.javaで保存し、実行するとこうなります。↓↓
7.ポリモーフィズムをする理由
-
オブジェクト指向では、あらゆる事象をオブジェクトとして捉える。 - そのため、
オブジェクトの数に比例してインスタンス化するクラスの数も増加する。 -
オブジェクトの数だけコードを書くと考えると途方もない数字となり書き切ることは難しい。 -
ポリモーフィズムは、オブジェクト同士の共通点を見つけ、抽象化することでコードの簡略化とコードの書く量を減らしている。
A,B,Cの3人がそれぞれ挨拶をするシステム
- A,B,Cが順番に挨拶をする。
- 挨拶は「
おはようございます」,「こんにちは」,「こんばんは」の3種類。 - 上記のようなシステムを作る際に
ポリモーフィズムをしなかった場合、下記のコードようにコード量が増えて複雑化してしまう。
Test1.java
package Test1;
public class Test1 {
public static void main(String[] args) {
// インスタンスの生成
GoodMorning[] goodmorning = {new GoodMorning("A"),new GoodMorning("B"),new GoodMorning("C")};
Hello[] hello = {new Hello("A"),new Hello("B"),new Hello("C")};
GoodEvening[] goodevening = {new GoodEvening("A"),new GoodEvening("B"),new GoodEvening("C")};
// 挨拶表示
for(int i = 0;i < goodmorning.length;i++) {
goodmorning[i].showGreeting();
}
for(int i = 0;i < hello.length;i++) {
hello[i].showGreeting();
}
for(int i = 0;i < goodevening.length;i++) {
goodevening[i].showGreeting();
}
}
}
Hello.java
package Test1;
public class Hello {
// インスタンス変数
String name;
// コンストラクタ
public Hello(String name) {
this.name = name;
}
// 挨拶の表示
void showGreeting() {
System.out.println(name+"さん、こんにちは。");
}
}
GoodMorning.java
package Test1;
public class GoodMorning{
// インスタンス変数
String name;
// コンストラクタ
public GoodMorning(String name) {
this.name = name;
}
// 挨拶の表示
void showGreeting() {
System.out.println(name+"さん、おはようございます。");
}
}
GoodEvening.java
package Test1;
public class GoodEvening {
// インスタンス変数
String name;
// コンストラクタ
public GoodEvening(String name) {
this.name = name;
}
// 挨拶の表示
void showGreeting() {
System.out.println(name+"さん、こんばんは。");
}
}
-
上記の文をコピーして、文字コードは
S-JISを指定し、ファイル名をTest1.java,GoodMorning.java,Hello.java,GoodEvening.javaで保存し、実行するとこうなります。↓↓

-
上記の例では、
ポリモーフィズムを使用していないため、配列が3つ存在し、それに対応したfor文が存在する。 -
ポリモーフィズムを使用して抽象化することで配列を1つにまとめることができる。 -
上記の例の
GoodMorning.java,Hello.java,GoodEvening.javaを抽象化すると以下のようになる。
Test1.java
package Test1;
public class Test1 {
public static void main(String[] args) {
// インスタンスの生成
Greeting[] greeting = {
new GoodMorning("A"),new GoodMorning("B"),new GoodMorning("C"),
new Hello("A"),new Hello("B"),new Hello("C"),
new GoodEvening("A"),new GoodEvening("B"),new GoodEvening("C")
};
// 挨拶表示
for(int i = 0;i < greeting.length;i++) {
greeting[i].showGreeting();
}
}
}
Greeting.java
package Test1;
public abstract class Greeting {
// インスタンス変数
private String name;
// コンストラクタ
public Greeting(String name) {
this.name = name;
}
// getter
public String getName() {
return name;
}
// 挨拶の表示
abstract void showGreeting();
}
Hello.java
package Test1;
public class Hello extends Greeting{
// コンストラクタ
public Hello(String name) {
super(name);
}
// 挨拶の表示
@Override
void showGreeting() {
System.out.println(getName()+"さん、こんにちは。");
}
}
GoodMorning.java
package Test1;
public class GoodMorning extends Greeting {
// コンストラクタ
public GoodMorning(String name) {
super(name);
}
// 挨拶の表示
@Override
void showGreeting() {
System.out.println(getName()+"さん、おはようございます。");
}
}
GoodEvening.java
package Test1;
public class GoodEvening extends Greeting {
// コンストラクタ
public GoodEvening(String name) {
super(name);
}
// 挨拶の表示
@Override
void showGreeting() {
System.out.println(getName()+"さん、こんばんは。");
}
}
- 上記の文をコピーして、文字コードは
S-JISを指定し、ファイル名をTest1.java,Greeting.java,GoodMorning.java,Hello.java,GoodEvening.javaで保存し、実行するとこうなります。↓↓
7.GitHub
GitHubにソースコードを公開しています。
