はじめに
こんにちは。Java Questの第2回へようこそ!
前回は、オブジェクト指向の基本である「クラス」と「インスタンス」について学びました。
クラスは設計図で、インスタンスは実体でしたね。
でも、こんな疑問を持ちませんでしたか?
「new Player()って、内部で何が起きてるの?」
「変数とインスタンスは、どう繋がってるの?」
「複数のキャラクターを管理するには?」
今回は、これらの疑問を解決していきます。
特に「参照」という概念は、Javaを理解する上で超重要なポイントです。
この記事で一緒に学ぶこと:
- インスタンス生成時のメモリの動き
- 参照型とは何か
- 配列で複数のインスタンスを管理する方法
- よくある間違い:参照の代入の罠
所要時間: 約15分です。前回よりも少し深い内容ですが、図解をたくさん使って分かりやすく説明します。
前提知識: 第1回の内容(クラスとインスタンスの基本)を理解していることを前提とします。
第1回をまだ読んでいない方は、先に第1回をご覧ください:
👉 第1回:オブジェクト指向って何?RPGで理解する超入門
今回のクエスト:冒険者パーティを結成しよう
前回は一人で戦いましたが、今回は仲間を集めてパーティを組みます。
強敵に立ち向かうには、戦士、魔法使い、僧侶といった異なる職業の冒険者が必要です。
複数のキャラクターをどう管理するか?それがこの回のテーマです。
new演算子の裏側:メモリで何が起きているか
まず、new Player()を実行したとき、コンピュータの中で何が起きているのか見ていきましょう。
コードの復習
/**
* プレイヤーインスタンスの作成例
*/
public class MemoryExample {
/**
* メインメソッド
* @param args コマンドライン引数
*/
public static void main(String[] args) {
// プレイヤーインスタンスを作成
Player hero = new Player();
// フィールドに値を設定
hero.name = "勇者";
hero.hp = 100;
}
}
この2行で、メモリ上では以下のことが起きています。
メモリの構造
コンピュータのメモリは、大きく分けて2つの領域があります。
1. スタック領域(Stack)
- 役割:変数(箱)を保存する場所
- 特徴:高速、容量は小さい、自動的に管理される
-
保存されるもの:
- ローカル変数
- メソッドの引数
- 参照(インスタンスの住所)
2. ヒープ領域(Heap)
- 役割:インスタンス(実体)を保存する場所
- 特徴:大容量、速度は普通、GCにより自動管理される
-
保存されるもの:
- newで作成したインスタンス
- インスタンスのフィールド
実行の流れ
Player hero = new Player();
この1行を分解すると:
ステップ1: new Player() でヒープにインスタンスを作成
- メモリ上のどこか(例:アドレス0x1A2B3C4D)にPlayerインスタンスが作られる
- フィールドは初期値で初期化される
- String型: null
- int型: 0
ステップ2: Player hero でスタックに変数を作成
- 変数heroがスタック上に作られる
- この変数は「参照」を保存する箱
ステップ3: = で参照を代入
- heroにインスタンスのアドレス(0x1A2B3C4D)が保存される
- これで、heroからインスタンスにアクセスできる
重要ポイント:
変数heroは、インスタンスそのものを持っているのではなく、
インスタンスが「どこにあるか」という情報(参照)を持っています。
参照型を理解する
Javaのデータ型は、大きく2種類に分けられます。
基本型(プリミティブ型)
int hp = 100; // 変数に値そのものが入る
double speed = 5.5; // 変数に値そのものが入る
boolean isAlive = true; // 変数に値そのものが入る
基本型の変数には、値そのものが直接入ります。
基本型の種類:
-
byte,short,int,long(整数) -
float,double(小数) -
char(文字) -
boolean(真偽値)
参照型
Player hero = new Player(); // 変数に参照(アドレス)が入る
String name = "勇者"; // 変数に参照が入る(Stringも参照型)
参照型の変数には、インスタンスの場所を示す参照が入ります。
参照型の種類:
- クラス(Player, String など)
- 配列
- インターフェース(後の回で学習)
違いを図で理解する
基本型の場合:
[変数 hp]
┌──────┐
│ 100 │ ← 値そのものが入っている
└──────┘
参照型の場合:
[変数 hero] [ヒープ上のインスタンス]
┌────────────┐ ┌─────────────────┐
│ 0x1A2B3C4D │ ----→ │ name: "勇者" │
└────────────┘ │ hp: 100 │
参照 │ attack: 15 │
└─────────────────┘
参照の代入で起きる「罠」
参照型を理解していないと、こんなバグに遭遇します。
よくある間違い
/**
* 参照の代入の罠を示すサンプル
*/
public class ReferenceCopyTrap {
/**
* メインメソッド
* @param args コマンドライン引数
*/
public static void main(String[] args) {
// 勇者を作成
Player hero = new Player();
hero.name = "勇者";
hero.hp = 100;
System.out.println("=== 最初の状態 ===");
System.out.println("hero.name: " + hero.name);
// heroをcopyに代入して「コピー」したつもり
Player copy = hero;
// copyの名前を変更
copy.name = "魔王";
System.out.println("\n=== copy.nameを変更した後 ===");
System.out.println("hero.name: " + hero.name); // どうなる?
System.out.println("copy.name: " + copy.name);
}
}
実行結果
=== 最初の状態 ===
hero.name: 勇者
=== copy.nameを変更した後 ===
hero.name: 魔王
copy.name: 魔王
えっ!? hero.nameまで変わってる!
なぜこうなるのか
Player copy = hero;
この代入では、インスタンスのコピーではなく、参照のコピーが行われています。
実際の動き:
[hero] [インスタンス]
┌───────┐ ┌───────────────┐
│ 0x100 │ ------→ │ name: "勇者" │
└───────┘ └───────────────┘
↑
[copy] │
┌───────┐ │
│ 0x100 │ -----------------┘
└───────┘
heroとcopyは、同じインスタンスを指しているのです!
間違った理解:
「copyに代入したから、別のインスタンスができた」
正しい理解:
「copyに参照を代入したので、同じインスタンスを2つの変数が指している」
本当にコピーしたい場合
インスタンスの内容を別のインスタンスにコピーしたい場合は:
/**
* インスタンスの内容をコピーする正しい方法
*/
public class CorrectCopy {
/**
* メインメソッド
* @param args コマンドライン引数
*/
public static void main(String[] args) {
// オリジナル
Player hero = new Player();
hero.name = "勇者";
hero.hp = 100;
hero.attack = 15;
// 新しいインスタンスを作成してコピー
Player copy = new Player(); // ← 新しいインスタンスを作る!
copy.name = hero.name; // フィールドを一つずつコピー(文字列は参照のコピー、値共有)
copy.hp = hero.hp;
copy.attack = hero.attack;
// これでcopyを変更してもheroは影響を受けない
copy.name = "戦士"; // 別の文字列を参照
System.out.println("hero.name: " + hero.name); // 勇者
System.out.println("copy.name: " + copy.name); // 戦士
}
}
重要:
-
newを使って新しいインスタンスを作る - フィールドを一つずつコピーする
配列で複数のインスタンスを管理する
さあ、いよいよパーティを組みましょう!
配列の基本
配列は、同じ型の変数を複数まとめて管理するための仕組みです。
/**
* 配列を使ってパーティを管理する例
*/
public class PartyManagement {
/**
* メインメソッド
* @param args コマンドライン引数
*/
public static void main(String[] args) {
System.out.println("=== パーティ編成開始 ===\n");
// ========================================
// Player型の配列を作成(箱を3つ用意)
// ========================================
Player[] party = new Player[3];
// この時点では、配列の中身はすべてnull
// party[0] = null
// party[1] = null
// party[2] = null
// ========================================
// 各要素にインスタンスを作成して代入
// ========================================
// 戦士を作成
party[0] = new Player();
party[0].name = "戦士アルフレッド";
party[0].hp = 120;
party[0].maxHp = 120;
party[0].attack = 20;
// 魔法使いを作成
party[1] = new Player();
party[1].name = "魔法使いメルリン";
party[1].hp = 80;
party[1].maxHp = 80;
party[1].attack = 30;
// 僧侶を作成
party[2] = new Player();
party[2].name = "僧侶エレナ";
party[2].hp = 90;
party[2].maxHp = 90;
party[2].attack = 10;
// ========================================
// パーティ全員の状態を表示
// ========================================
System.out.println("=== パーティメンバー ===");
// for文で配列の全要素を処理
for (int i = 0; i < party.length; i++) {
System.out.println("\n--- メンバー" + (i + 1) + " ---");
party[i].showStatus();
}
}
}
配列の仕組み
Player[] party = new Player[3];
この行では:
- 配列オブジェクトが作成される(3つの参照を保存できる)
- 各要素は初期値null
- party変数は配列への参照を保持
party[0] = new Player();
この行では:
- 新しいPlayerインスタンスが作成される
- 配列の0番目の要素に参照が代入される
メモリイメージ:
[party配列] [インスタンス群]
┌──────────┐
│ [0] -----│-----→ Player(戦士)
│ [1] -----│-----→ Player(魔法使い)
│ [2] -----│-----→ Player(僧侶)
└──────────┘
配列の便利さ
配列を使うと、for文でまとめて処理できます:
/**
* パーティ全員に共通の処理を実行する例
*/
public class PartyOperations {
/**
* メインメソッド
* @param args コマンドライン引数
*/
public static void main(String[] args) {
// パーティを準備(省略)
Player[] party = new Player[3];
// ... 各メンバーを作成 ...
// ========================================
// パーティ全員を10移動させる
// ========================================
System.out.println("=== パーティ全員が移動 ===");
for (int i = 0; i < party.length; i++) {
party[i].move(10, 0);
}
// ========================================
// パーティ全員がダメージを受ける
// ========================================
System.out.println("\n=== 敵の全体攻撃! ===");
for (int i = 0; i < party.length; i++) {
party[i].takeDamage(15);
}
// ========================================
// 生き残っているメンバーを確認
// ========================================
System.out.println("\n=== 生存確認 ===");
int aliveCount = 0;
for (int i = 0; i < party.length; i++) {
if (party[i].hp > 0) {
System.out.println(party[i].name + "は生きている");
aliveCount++;
} else {
System.out.println(party[i].name + "は倒れた...");
}
}
System.out.println("\n生存者: " + aliveCount + "人");
}
}
配列のメリット:
- 複数のインスタンスをまとめて管理
- for文で一括処理が可能
- 要素数を動的に扱える(party.length)
パーティ vs 敵の群れ:実践的な例
それでは、パーティで敵の群れと戦うプログラムを作ってみましょう。
/**
* パーティ戦闘システムのサンプル
*/
public class PartyBattle {
/**
* メインメソッド
* @param args コマンドライン引数
*/
public static void main(String[] args) {
System.out.println("=== Java Quest 第2章:パーティの冒険 ===\n");
// ========================================
// パーティを編成(3人)
// ========================================
Player[] party = new Player[3];
party[0] = new Player();
party[0].name = "戦士";
party[0].hp = 120;
party[0].maxHp = 120;
party[0].attack = 20;
party[1] = new Player();
party[1].name = "魔法使い";
party[1].hp = 80;
party[1].maxHp = 80;
party[1].attack = 30;
party[2] = new Player();
party[2].name = "僧侶";
party[2].hp = 90;
party[2].maxHp = 90;
party[2].attack = 10;
// ========================================
// 敵の群れを作成(5体)
// ========================================
Player[] enemies = new Player[5];
// スライム2体
for (int i = 0; i < 2; i++) {
enemies[i] = new Player();
enemies[i].name = "スライム" + (i + 1);
enemies[i].hp = 30;
enemies[i].maxHp = 30;
enemies[i].attack = 5;
}
// ゴブリン2体
for (int i = 2; i < 4; i++) {
enemies[i] = new Player();
enemies[i].name = "ゴブリン" + (i - 1);
enemies[i].hp = 50;
enemies[i].maxHp = 50;
enemies[i].attack = 8;
}
// ドラゴン1体
enemies[4] = new Player();
enemies[4].name = "ドラゴン";
enemies[4].hp = 150;
enemies[4].maxHp = 150;
enemies[4].attack = 25;
// ========================================
// 戦闘開始
// ========================================
System.out.println("=== 戦闘開始! ===\n");
// パーティの全員が攻撃
System.out.println("--- パーティの攻撃ターン ---");
for (int i = 0; i < party.length; i++) {
// 生きている敵を探す
for (int j = 0; j < enemies.length; j++) {
if (enemies[j].hp > 0) {
// 最初に見つけた敵を攻撃
party[i].attackEnemy(enemies[j]);
System.out.println();
break; // 1体攻撃したら次のメンバーへ
}
}
}
// 敵の反撃(生きている敵のみ)
System.out.println("--- 敵の反撃ターン ---");
for (int i = 0; i < enemies.length; i++) {
if (enemies[i].hp > 0) {
// ランダムにパーティメンバーを攻撃(ここでは0番目を攻撃)
enemies[i].attackEnemy(party[0]);
System.out.println();
}
}
// ========================================
// 戦闘結果の集計
// ========================================
System.out.println("=== 戦闘終了 ===\n");
// パーティの状態
System.out.println("--- パーティの状態 ---");
int partyAlive = 0;
for (int i = 0; i < party.length; i++) {
System.out.print(party[i].name + ": HP " + party[i].hp + "/" + party[i].maxHp);
if (party[i].hp > 0) {
System.out.println(" (生存)");
partyAlive++;
} else {
System.out.println(" (戦闘不能)");
}
}
System.out.println();
// 敵の状態
System.out.println("--- 敵の状態 ---");
int enemiesAlive = 0;
for (int i = 0; i < enemies.length; i++) {
System.out.print(enemies[i].name + ": HP " + enemies[i].hp + "/" + enemies[i].maxHp);
if (enemies[i].hp > 0) {
System.out.println(" (生存)");
enemiesAlive++;
} else {
System.out.println(" (撃破)");
}
}
System.out.println();
// 勝敗判定
if (partyAlive > 0 && enemiesAlive == 0) {
System.out.println("パーティの勝利!");
} else if (partyAlive == 0) {
System.out.println("パーティは全滅した...");
} else {
System.out.println("戦闘は続く...");
}
}
}
このコードのポイント:
- 2つの配列で味方と敵を管理
- for文のネストで全員を処理
- 配列の長さ(party.length, enemies.length)を活用
- 条件分岐(hp > 0)で生存確認
初学者がよくハマるポイント
❌ 間違い1:配列を作っただけでインスタンスができると思う
Player[] party = new Player[3];
// この時点では、partyの中身は全部null!
party[0].name = "戦士"; // エラー!NullPointerException
なぜエラーになる?
new Player[3]は、「Player型の参照を3つ保存できる箱」を作っただけです。
中にPlayerインスタンスは入っていません(全部null)。
正しい書き方:
Player[] party = new Player[3];
// 各要素にインスタンスを作成
party[0] = new Player(); // ← これが必要!
party[0].name = "戦士"; // OK!
❌ 間違い2:配列のインデックスを間違える
Player[] party = new Player[3]; // 要素数3
party[0] = new Player(); // OK(インデックス0)
party[1] = new Player(); // OK(インデックス1)
party[2] = new Player(); // OK(インデックス2)
party[3] = new Player(); // エラー!ArrayIndexOutOfBoundsException
配列のインデックスは0から始まります!
- 要素数3の配列: インデックスは0, 1, 2
- 要素数nの配列: インデックスは0 〜 n-1
❌ 間違い3:参照のコピーと実体のコピーを混同
Player hero = new Player();
hero.name = "勇者";
Player copy = hero; // ← これは参照のコピー!
// heroとcopyは同じインスタンスを指している
copy.name = "戦士";
System.out.println(hero.name); // "戦士" と表示される
本当にコピーしたい場合:
Player hero = new Player();
hero.name = "勇者";
Player copy = new Player(); // ← 新しいインスタンスを作る
copy.name = hero.name; // フィールドをコピー
デバッグのヒント
NullPointerExceptionが出たら
Exception in thread "main" java.lang.NullPointerException
at PartyManagement.main(PartyManagement.java:15)
確認すること:
- 配列の要素に
newでインスタンスを作成したか? - 変数がnullのままになっていないか?
デバッグ方法:
Player[] party = new Player[3];
// nullチェックを追加
if (party[0] == null) {
System.out.println("party[0]はnullです!インスタンスを作成してください");
} else {
party[0].showStatus();
}
ArrayIndexOutOfBoundsExceptionが出たら
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at PartyBattle.main(PartyBattle.java:20)
確認すること:
- 配列のサイズを確認(.length)
- アクセスしているインデックスが範囲内か
デバッグ方法:
Player[] party = new Player[3];
System.out.println("配列のサイズ: " + party.length);
// 安全なアクセス
for (int i = 0; i < party.length; i++) { // ← lengthより小さい間だけループ
// party[i]を使う
}
参照のコピーバグを見つけるには
Player hero = new Player();
hero.name = "勇者";
Player copy = hero;
// 同じインスタンスを指しているか確認
if (hero == copy) {
System.out.println("heroとcopyは同じインスタンスを指しています");
} else {
System.out.println("heroとcopyは別のインスタンスです");
}
注意:
==演算子は、参照が同じかどうかを比較します。
内容が同じかを比較するには、equalsメソッドを使います(後の回で学習)。
実際に手を動かして、理解を深めましょう!
基本問題
問題1: 5人パーティを作成しよう
Player配列を使って、以下の5人のパーティを作成してください。
| 番号 | 名前 | HP | 攻撃力 |
|---|---|---|---|
| 0 | 戦士 | 120 | 20 |
| 1 | 魔法使い | 80 | 30 |
| 2 | 僧侶 | 90 | 10 |
| 3 | 盗賊 | 100 | 15 |
| 4 | 騎士 | 150 | 25 |
全員の状態をfor文で表示してください。
問題2: 敵の群れを作成しよう
スライム3体のインスタンスを配列で管理してください。
- 名前:スライム1、スライム2、スライム3
- HP:30
- 攻撃力:5
for文を使って効率的に作成してください。
解答例を見る
public class PlayerDemo {
public static void main(String[] args) {
// ========================================
// 問題1.パーティを編成(5人)
// ========================================
Player[] party = new Player[5];
party[0] = new Player();
party[0].name = "戦士";
party[0].hp = 120;
party[0].maxHp = 120;
party[0].attack = 20;
party[1] = new Player();
party[1].name = "魔法使い";
party[1].hp = 80;
party[1].maxHp = 80;
party[1].attack = 30;
party[2] = new Player();
party[2].name = "僧侶";
party[2].hp = 90;
party[2].maxHp = 90;
party[2].attack = 10;
party[3] = new Player();
party[3].name = "盗賊";
party[3].hp = 100;
party[3].maxHp = 100;
party[3].attack = 15;
party[4] = new Player();
party[4].name = "騎士";
party[4].hp = 150;
party[4].maxHp = 150;
party[4].attack = 10;
for (int i = 0; i < party.length; i++) {
party[i].showStatus();
}
// ========================================
// 問題2.敵の群れを作成
// ========================================
// スライム3体
Player[] enemies = new Player[3];
for (int i = 0; i < 3; i++) {
enemies[i] = new Player();
enemies[i].name = "スライム" + (i + 1);
enemies[i].hp = 30;
enemies[i].maxHp = 30;
enemies[i].attack = 5;
enemies[i].showStatus();
}
}
}
実行結果
===== プレイヤー情報 =====
名前: 戦士
位置: (0, 0)
HP: 120 / 120
攻撃力: 20
=========================
===== プレイヤー情報 =====
名前: 魔法使い
位置: (0, 0)
HP: 80 / 80
攻撃力: 30
=========================
===== プレイヤー情報 =====
名前: 僧侶
位置: (0, 0)
HP: 90 / 90
攻撃力: 10
=========================
===== プレイヤー情報 =====
名前: 盗賊
位置: (0, 0)
HP: 100 / 100
攻撃力: 15
=========================
===== プレイヤー情報 =====
名前: 騎士
位置: (0, 0)
HP: 150 / 150
攻撃力: 10
=========================
===== プレイヤー情報 =====
名前: スライム1
位置: (0, 0)
HP: 30 / 30
攻撃力: 5
=========================
===== プレイヤー情報 =====
名前: スライム2
位置: (0, 0)
HP: 30 / 30
攻撃力: 5
=========================
===== プレイヤー情報 =====
名前: スライム3
位置: (0, 0)
HP: 30 / 30
攻撃力: 5
=========================
応用問題
問題3: 参照のコピーを確認しよう
以下のコードを実行すると、hero.nameとcopy.nameはそれぞれ何が表示されるか予想してから、
実際に実行して確認してください。
Player hero = new Player();
hero.name = "勇者";
Player copy = hero;
copy.name = "戦士";
System.out.println("hero.name: " + hero.name);
System.out.println("copy.name: " + copy.name);
次に、heroとcopyが別のインスタンスになるように修正してください。
解答例を見る
public class CopyDemo {
public static void main(String[] args) {
// 修正前
Player hero = new Player();
hero.name = "勇者";
Player copy = hero;
copy.name = "戦士";
System.out.println("hero.name: " + hero.name);
System.out.println("copy.name: " + copy.name);
System.out.println();
// heroとcopyが別のインスタンスになるように修正
copy = new Player();
copy.name = "戦士";
hero.name = "勇者";
System.out.println("hero.name: " + hero.name);
System.out.println("copy.name: " + copy.name);
}
}
実行結果
hero.name: 戦士
copy.name: 戦士
hero.name: 勇者
copy.name: 戦士
問題4: パーティの平均HPを計算しよう
パーティ全員の平均HPを計算して表示するプログラムを作成してください。
仕様:
- パーティは3人
- 各メンバーのHPは異なる
- for文を使ってHPの合計を計算
- 合計 ÷ メンバー数で平均を求める
ヒント:
int totalHp = 0;
for (int i = 0; i < party.length; i++) {
totalHp += party[i].hp;
}
double averageHp = (double)totalHp / party.length;
解答例を見る
public class AvgDemo {
public static void main(String[] args) {
// ========================================
// 問題5.HPが最も高いメンバーを見つけよう
// ========================================
Player[] party = new Player[5];
party[0] = new Player();
party[0].name = "戦士";
party[0].hp = 120;
party[0].maxHp = 120;
party[0].attack = 20;
party[1] = new Player();
party[1].name = "魔法使い";
party[1].hp = 80;
party[1].maxHp = 80;
party[1].attack = 30;
party[2] = new Player();
party[2].name = "僧侶";
party[2].hp = 90;
party[2].maxHp = 90;
party[2].attack = 10;
party[3] = new Player();
party[3].name = "盗賊";
party[3].hp = 100;
party[3].maxHp = 100;
party[3].attack = 15;
party[4] = new Player();
party[4].name = "騎士";
party[4].hp = 150;
party[4].maxHp = 150;
party[4].attack = 10;
int totalHp = 0;
for(int i =0; i < party.length; i++) {
totalHp += party[i].hp;
}
// 平均を求める
double averageHp = (double)totalHp / party.length;
System.out.println("平均は"+averageHp);
}
}
実行結果
平均は108.0
問題5: HPが最も高いメンバーを見つけよう
パーティの中で、HPが最も高いメンバーの名前とHPを表示するプログラムを作成してください。
※HPが最も高いメンバーの名前とHPを表示できれば、下記仕様を満たさなくてもOK
仕様:
- for文で全メンバーを確認
- 最大HPと、そのメンバーのインデックスを記録
- 最後に結果を表示
解答例を見る
public class MaxDemo {
public static void main(String[] args) {
// ========================================
// 問題5.HPが最も高いメンバーを見つけよう
// ========================================
Player[] party = new Player[5];
party[0] = new Player();
party[0].name = "戦士";
party[0].hp = 120;
party[0].maxHp = 120;
party[0].attack = 20;
party[1] = new Player();
party[1].name = "魔法使い";
party[1].hp = 80;
party[1].maxHp = 80;
party[1].attack = 30;
party[2] = new Player();
party[2].name = "僧侶";
party[2].hp = 90;
party[2].maxHp = 90;
party[2].attack = 10;
party[3] = new Player();
party[3].name = "盗賊";
party[3].hp = 100;
party[3].maxHp = 100;
party[3].attack = 15;
party[4] = new Player();
party[4].name = "騎士";
party[4].hp = 150;
party[4].maxHp = 150;
party[4].attack = 10;
// 現時点の最大HPのメンバーを設定(配列0の情報で初期化)
Player user = party[0];
// for文で全メンバーを確認
for (int i = 0; i < party.length; i++) {
// 最大HPと、そのメンバーのインデックスを記録
if(user.hp < party[i].hp) {
user = party[i];
}
}
// 最後に結果表示
user.showStatus();
}
}
実行結果
===== プレイヤー情報 =====
名前: 騎士
位置: (0, 0)
HP: 150 / 150
攻撃力: 10
=========================
お疲れ様でした!第2回では、インスタンスと参照について深く学びました。
重要ポイント:
1.メモリは2つの領域に分かれる
- スタック:変数と参照を保存
- ヒープ:インスタンスを保存
2.参照型の変数は、インスタンスの「場所」を保持
- 変数にはアドレス(参照)が入る
- 実体(インスタンス)はヒープにある
3.参照のコピーに注意
-
Player copy = hero;は参照のコピー - 本当にコピーするには
newで新しいインスタンスを作る
4.配列で複数のインスタンスを管理
-
Player[] party = new Player[3];で配列を作成 - 各要素に
new Player()でインスタンスを代入 - for文でまとめて処理できる
5.配列とインデックス
- インデックスは0から始まる
- 配列のサイズは
.lengthで取得 - 範囲外アクセスに注意
この知識があれば、複雑なプログラムも怖くありません!
第3回:フィールドとメソッド - クラスの中身を深く理解する
次回は、フィールドとメソッドについてさらに詳しく学びます。
- static(静的)とは何か
- thisキーワードの使い方
- メソッドのオーバーロード
- フィールドとローカル変数の違い
さらに強力な冒険者クラスを作っていきましょう!
- Oracle Java Tutorials: Arrays
- Oracle Java Tutorials: Primitive Data Types
- Java API仕様書(日本語版)
- 第1回:オブジェクト指向って何?RPGで理解する超入門
- 第2回:オブジェクト指向って何?RPGで理解する超入門 (配列とループ)(本記事)
- 第3回:フィールドとメソッド(次回)
- 第4回:コンストラクタ
- 第5回:カプセル化
- 第6回:参照型を理解する
- 第7回:継承
- 第8回:ポリモーフィズム
- 第9回:抽象クラスとインターフェース
- 第10回:総合演習 - RPGバトルシステム構築
© 2025 Java Quest - オブジェクト指向って何?RPGで理解する超入門
All Rights Reserved.
本記事は教育目的で作成されています。RPGの例を通じてプログラミング概念を楽しく学習できることを目指しています。










