多様性・多態性・多相性・ポリモーフィズム・オーバーライド・オーバーロード・インターフェース・カプセル化・抽象クラス・例外処理を一覧整理
Javaの学習を始めると、こんな言葉が次々に出てきます。
- 多態性
- オーバーライド
- オーバーロード
- インターフェース
- カプセル化
- 抽象クラス
- 例外処理
ここでつまずく理由は、言葉が難しいわりに、何を言っているのかイメージしづらいからです。
この記事では、ポケモンの世界にたとえながら、Java初学者が最初に混乱しやすい重要キーワードをまとめて整理します。
細かい文法を覚える前に、まずは
「それって結局どういうこと?」
が頭に入ることを重視しています。
目次
多態性とは
**多態性(ポリモーフィズム)**とは、
同じ命令を出しても、相手によって違う動きをすることです。
ポケモンでたとえると、同じ「技を使え」という命令でも、ポケモンごとに結果が変わります。
- ピカチュウのでんきショック → ダメージ10
- ライチュウのでんきショック → ダメージ50
- 特別なポケモンのでんきショック → ダメージ60+追加効果
つまり、呼び出し方は同じでも、中身の動きが違うのが多態性です。
Javaでは、親クラスの型でまとめて扱っていても、実際には子クラスごとの動作が実行されます。
class Pokemon {
void attack() {
System.out.println("こうげき!");
}
}
class Pikachu extends Pokemon {
@Override
void attack() {
System.out.println("ピカチュウのでんきショック!");
}
}
class Raichu extends Pokemon {
@Override
void attack() {
System.out.println("ライチュウのでんきショック!");
}
}
public class Main {
public static void main(String[] args) {
Pokemon p1 = new Pikachu();
Pokemon p2 = new Raichu();
p1.attack();
p2.attack();
}
}
出力例:
ピカチュウのでんきショック!
ライチュウのでんきショック!
このように、Pokemon 型で扱っているのに、実際の中身に応じて動作が変わるのが多態性です。
オーバーライドとは
オーバーライドとは、
親クラスで定義されたメソッドを、子クラスで自分用に上書きすることです。
ポケモンで言えば、親の「共通技」を、進化後や種類ごとに自分向けの技として作り直すイメージです。
- 親クラスの技:こうげきする
- ピカチュウ版:でんきショック
- ヒトカゲ版:ひのこ
class Pokemon {
void attack() {
System.out.println("ポケモンの基本こうげき");
}
}
class Pikachu extends Pokemon {
@Override
void attack() {
System.out.println("ピカチュウのでんきショック");
}
}
class Charmander extends Pokemon {
@Override
void attack() {
System.out.println("ヒトカゲのひのこ");
}
}
ポイントは、メソッド名や引数は同じまま、中身だけ変えることです。
@Override を付けると、「これは親クラスのメソッドを上書きしています」と明示できるので、書き間違いも見つけやすくなります。
オーバーロードとは
オーバーロードとは、
同じ名前のメソッドを、引数の違いで複数用意することです。
ポケモンでたとえると、「でんきショック」という同じ技名でも、使い方を分けるイメージです。
- 単体に使うでんきショック
- 全体に使うでんきショック
- 威力を指定して使うでんきショック
class Pikachu {
void thunderShock() {
System.out.println("通常のでんきショック!");
}
void thunderShock(String target) {
System.out.println(target + " にでんきショック!");
}
void thunderShock(String target, int power) {
System.out.println(target + " に威力 " + power + " のでんきショック!");
}
}
public class Main {
public static void main(String[] args) {
Pikachu pikachu = new Pikachu();
pikachu.thunderShock();
pikachu.thunderShock("ゼニガメ");
pikachu.thunderShock("ギャラドス", 100);
}
}
出力例:
通常のでんきショック!
ゼニガメ にでんきショック!
ギャラドス に威力 100 のでんきショック!
ポイントは、メソッド名は同じで、引数の個数や型が違うことです。
インターフェースとは
インターフェースとは、
「この種類のものは、こういうことができます」という約束だけを決めたものです。
ポケモンで言えば、ポケモンなら共通して持っている仕様の一覧です。
- モンスターボールに入れる
- 呼び出せる
- 鳴ける
- 技を使える
ただし、どうやって鳴くか、どんな技を使うかまではインターフェースには書きません。
それは各ポケモンが自分で実装します。
interface Pokemon {
void cry();
void attack();
}
class Pikachu implements Pokemon {
public void cry() {
System.out.println("ピカピカ!");
}
public void attack() {
System.out.println("でんきショック!");
}
}
class Squirtle implements Pokemon {
public void cry() {
System.out.println("ゼニゼニ!");
}
public void attack() {
System.out.println("みずでっぽう!");
}
}
インターフェースは、
何ができるかを揃えるためのルールブック
と考えるとわかりやすいです。
カプセル化とは
カプセル化とは、
大事なデータを外から勝手に触れないようにして、安全な操作だけを公開することです。
ポケモンでたとえると、ポケモンのHPや状態は、他人が勝手に書き換えられないようにして、トレーナーが決められた方法でだけ指示を出せるようにするイメージです。
class PokemonStatus {
private int hp;
public PokemonStatus(int hp) {
this.hp = hp;
}
public void takeDamage(int damage) {
if (damage < 0) {
return;
}
hp -= damage;
if (hp < 0) {
hp = 0;
}
}
public int getHp() {
return hp;
}
}
public class Main {
public static void main(String[] args) {
PokemonStatus pikachu = new PokemonStatus(100);
pikachu.takeDamage(30);
System.out.println("現在のHP: " + pikachu.getHp());
}
}
hp を private にしているので、外から直接
// コンパイルエラーになる想定のコード
// pikachu.hp = -9999;
のような危険な変更はできません。
つまりカプセル化は、
「自由に触らせないことで、壊れにくくする仕組み」 です。
抽象クラスとは
抽象クラスとは、
共通部分だけをまとめた未完成の設計図です。
ポケモンで言えば、「ポケモンならこういう性質を持つよね」という共通点だけを先に決めておくイメージです。
- 名前がある
- 攻撃できる
- 鳴ける
でも、実際にどんな鳴き声か、どんな攻撃かは種類ごとに違います。
そのため、親クラスでは未完成のままにして、子クラスで完成させます。
abstract class AbstractPokemon {
String name;
AbstractPokemon(String name) {
this.name = name;
}
void introduce() {
System.out.println("わたしは " + name + " です");
}
abstract void attack();
}
class Pikachu2 extends AbstractPokemon {
Pikachu2() {
super("ピカチュウ");
}
@Override
void attack() {
System.out.println("でんきショック!");
}
}
class Charmander2 extends AbstractPokemon {
Charmander2() {
super("ヒトカゲ");
}
@Override
void attack() {
System.out.println("ひのこ!");
}
}
抽象クラスは、
共通部分は親でまとめたい。でも細かい実装は子に任せたい
ときに使います。
例外処理とは
例外処理とは、
プログラム中で起こる予想外のトラブルに備える仕組みです。
ポケモンバトルで言えば、こんな状況です。
- 麻痺して技が出せない
- 回復アイテムが空っぽ
- 存在しないポケモンを選ぼうとした
そんなとき、何の備えもないとプログラムは途中で止まりやすくなります。
そこで Java では、try-catch を使って「問題が起きたときの対応」を用意します。
public class ExceptionSample {
public static void main(String[] args) {
try {
int[] team = {1, 2, 3};
// ありえない番号のポケモンを選んでしまった
System.out.println(team[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("そんな場所にポケモンはいません!");
}
System.out.println("ゲームは続行できます。");
}
}
出力例:
そんな場所にポケモンはいません!
ゲームは続行できます。
ここではイメージだけを紹介しました。
詳しくは別の記事で、try-catch-finally や throw、throws などを体系的に学ぶと理解が深まります。
Javaキーワード早見表(補足資料)
最後に、学習時に名前がごちゃごちゃしやすい Javaの基本キーワードの早見表 を載せておきます。
| カテゴリ | 用語 | 対応箇所のコード例 / 概要 |
|---|---|---|
| 基本構成 | package |
package com.example.game;(プログラムの配置場所を定義) |
| import |
import java.util.ArrayList;(外部ライブラリや他パッケージの読み込み) |
|
| 構造定義 | クラス(class) |
public class Monster { ... }(データと処理をまとめた設計図) |
| フィールド(field) |
private String name;(クラス内で保持するデータ・状態) |
|
| メソッド(method) |
public void cry() { ... }(クラスが実行する振る舞い・処理) |
|
| 実体化 | オブジェクト / インスタンス |
new Monster("ピカチュウ")(設計図を元にメモリ上に生成された実体) |
| データ要素 | 変数(variable) |
int level = 5;(値を一時的に格納する箱の総称) |
| 型(type) |
int, String, boolean(変数が扱うデータの種類) |
|
| リテラル(literal) |
"ピカチュウ", 10, null(ソースコードに直接書かれた具体的な値) |
|
| 自己・継承 | this |
this.name = name;(自分自身のインスタンスを指し示すキーワード) |
| super |
super();(親クラスのコンストラクタやメソッドを呼び出す際に使用) |
|
| 制御・制限 | アクセス修飾子 |
public / private / protected(利用可能な範囲を制限する) |
| static |
private static int count;(インスタンスを作らずとも共有される静的要素) |
|
| final |
public final void display()(値の変更やメソッドの上書きを禁止する) |
学習中に「この単語なんだっけ?」と思ったら、ここに戻ってきて軽く確認してもらえると役に立つはずです。
まとめ
Javaの重要キーワードは、言葉だけ見ると難しく感じます。
でも、ポケモンでイメージすると整理しやすくなります。
- 多態性:同じ命令でも、ポケモンごとに違う動きをする
- オーバーライド:親の技を子が自分向けに上書きする
- オーバーロード:同じ名前の技を、引数違いで使い分ける
- インターフェース:できることの約束だけを決める
- カプセル化:中身を勝手に触れないように守る
- 抽象クラス:共通部分だけを持つ未完成の設計図
- 例外処理:予想外のトラブルに備える仕組み
- キーワード早見表:コードを読むときの「用語辞書」として使える
文法を丸暗記するより先に、
「これは何のためにあるのか」
を掴めると、その後の学習がかなり楽になります。
ゲームをプレイするときも先に説明書を暗記しませんよね。
先にイメージを掴んで進んでいきましょう!