パッケージ

パッケージ(package)

パッケージはJavaクラスファイルを機能ごとに分類する仕組みで、クラスファイルの先頭行に「package」で指定します。

package パッケージ名

インポート(import)

作成したクラスファイルを利用するときに、同じパッケージファイルは自動認識されるます。しかし、パッケージ名が違う場合はインポートが必要になります。

import パッケージ名.クラス名

インポートの例

「Character」と「Monster」が別パッケージに作成されたとします。

ファイル構成

 src/
    └── character/
            ├── App.java
            ├── Character.java
            ├── Wizard.java
            └── Warrior.java
    └── monster/
            └── Monster.java

「Character」から「Monster」を使うときは、パッケージが「character」と「monster」で違うのでインポートが必要です。Eclipseではクラス名が複数なければ原則自動でインポートが入力されます。

package character;

//パッケージが違うので、パッケージ名を指定したクラスのインポートが必要
import monster.Monster;

public class Character {

    //別パッケージのフィールド定義
    Monster monster;

}

インポートの利用

ファイル構成

src/
    └── character/
            ├── App.java
            ├── Character.java
            ├── Wizard.java
            └── Warrior.java
    └── monster/
            └── Monster.java

Monsterクラスの作成

「monster」パッケージに「Monster」クラスを作成します。isAlive() メソッドは、hpが0より大きい時に「true」になります。

Monster.java
package monster;

public class Monster {

	public String name;
	public int hp;
	public int mp;
	public int attackPower;
	public int defencePower;

	public Monster() {
		super();

		this.name = "スライム";
		this.hp = 5;
		this.mp = 0;
		this.attackPower = 2;
		this.defencePower = 1;
	}

	public boolean isAlive() {
		return (this.hp > 0);
	}
}

別パッケージのクラスを利用

「Character」クラスに attack() メソッドを追加します。ここでは別パッケージの「Monster」を引数として攻撃処理します。

Character.java
	public void attack(Monster monster) {
		int damage = this.attackPower - monster.defencePower;
		if (damage > 0) monster.hp -= damage;
	}

メインプログラムで攻撃

メインプログラムで、「Monster」への攻撃を実行します。攻撃後に「Monster」のステータスを確認してみましょう。

App.java
package character;

//Eclipseで自動インポート
import monster.Monster;

public class App {

	public static void main(String[] args) {
		Wizard wizard = new Wizard("アリス");
		wizard.greet("こんにちは");
		wizard.showStatus();
		
		Warrior warrior = new Warrior("ボブ");
		warrior.greet("どーも");
		warrior.showStatus();
		
		Monster monster = new Monster();
		warrior.attack(monster);
		
		System.out.println(monster.hp);
		System.out.println(monster.isAlive());
	}
	
}

monsterインスタンスの hp と isAlive() の結果が確認できました。

結果
...
-4
false

パッケージ指定

パッケージをインポートせずに、明示的にパッケージ付きの外部クラスで記述することもできます。

同一クラスの場合

例えば、同じクラス「User」がそれぞれ「sample1」「sample2」のパッケージに存在したとします。

この場合、メインプログラムで両方のUserをインポートできません。

明示的ににインポート

異なるパッケージのUserクラスを使うときは、明示的にパッケージを指定することになります。ただ、このような設計はあまりよいとは言えないでしょう。

App.java
package sample3;

public class App {

	public static void main(String[] args) {
		sample1.User user1 = new sample1.User();
		sample2.User user2 = new sample2.User();
	}
}

既存のクラスファイルを開く

Eclipseでクラスを右クリックすると、既存のクラスファイルにアクセスすることができます。

対象のクラスファイルが開きました。「String」クラスは「java.lang」パッケージに指定されています。

クラスファイルにどのような機能があるか、調べるのに利用するとよいでしょう。

演習

以下のファイル構成があります。

src/
    └── user/
            └── User.java
    └── item/
            └── Food.java

問題1

「Food」クラスのパッケージで正しいのはどれですか?

1)package user;

2)package item;

3)import user;

4)import item;

問題2

「User」クラスで「Food」クラスをインポートする記述で正しいのはどれですか?

1)package Food;

2)package item.Food;

3)import Food;

4)import item.Food;