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にソースコードを公開しています。