Java超|異なるパッケージのクラスを使う

別パッケージのクラスを使うなら、公開設定と住所指定がカギ。public と パッケージ名.クラス名 を使えば、離れた棚の戦士クラスも正しく連携できます。

ここまでで、クラスをファイルごとに分けること、そして同じパッケージにクラスをまとめることを学んできました。

同じパッケージにあるクラス同士は、同じ棚に置かれた巻物のように、自然に連携しやすい関係でした。

たとえば、pa パッケージの中に SaiyanWarrior クラスと Sample3 クラスがあれば、Sample3 から SaiyanWarrior をそのまま使いやすくなります。

しかし、実際のJava開発では、いつも同じパッケージのクラスだけを使うわけではありません。

大きなプログラムでは、役割ごとにパッケージを分けることがよくあります。

パッケージ役割のイメージ
pa学習用、基本クラス用
pb実行用、確認用
pc共通部品、利用されるクラス用
battle戦闘処理用
mission任務管理用

ドラゴンボール風にたとえると、戦士管理本部にはいろいろな部署があります。

サイヤ人戦士の名簿を管理する棚、任務書を管理する棚、戦闘装備を管理する棚、気の技を管理する棚が分かれているようなものです。

このとき、pb パッケージにある実行用クラスから、pc パッケージにあるサイヤ人戦士クラスを使いたい場面が出てきます。

ただし、異なるパッケージのクラスは、同じパッケージのクラスのように、クラス名だけでいつでも使えるわけではありません。

Javaでは、異なるパッケージのクラスを使うときに、次の2つが大切になります。

必要なこと内容
利用されるクラスを public にする別パッケージから使えるように公開する
パッケージ名.クラス名で指定するどのパッケージのクラスかを明示する

この2つがそろうと、別のパッケージにあるクラスも正しく利用できるようになります。

異なるパッケージに分けると何が起こるのか

Javaでは、クラスを別々のパッケージに所属させることができます。

たとえば、次のように分けることができます。

クラス所属パッケージ役割
SaiyanWarriorpcサイヤ人戦士の情報を管理する
Sample4pbSaiyanWarrior を使おうとする実行用クラス
Sample5pbpc.SaiyanWarrior を正しく使う実行用クラス

このように分けると、役割ごとにクラスを整理できます。

ドラゴンボール風にたとえると、SaiyanWarrior は pc の棚に置かれた戦士名簿です。
Sample4 や Sample5 は pb の棚に置かれた出撃指令書です。

棚が違うため、Sample4 や Sample5 から SaiyanWarrior を使うには、どの棚にある SaiyanWarrior なのかをJavaに伝える必要があります。

同じパッケージなら、クラス名だけで見つかる場面が多いです。
しかし、別パッケージでは、クラス名だけでは場所が分かりません。

状況書き方の考え方
同じパッケージのクラスを使うクラス名だけで使いやすい
異なるパッケージのクラスを使うパッケージ名.クラス名で場所を示す

なぜそのままでは使えないのか

Javaでは、クラス名だけを書いた場合、まず同じパッケージの中にあるクラスとして探されます。

たとえば、pb パッケージの Sample4 クラスの中で、次のように書いたとします。

SaiyanWarrior warrior1 = new SaiyanWarrior();
SaiyanWarrior warrior1 = new SaiyanWarrior();

このとき、Javaはまず pb パッケージの中に SaiyanWarrior クラスがあるものとして探します。

しかし、使いたい SaiyanWarrior クラスが pc パッケージにある場合、pb の中には SaiyanWarrior がありません。

そのため、Javaは SaiyanWarrior を見つけられず、コンパイルエラーになります。

書き方Javaが探す場所結果
SaiyanWarriorまず同じ pb パッケージpb にないので見つからない
pc.SaiyanWarriorpc パッケージ場所を明示しているので探せる

ドラゴンボール風にたとえると、pb の棚にある戦士名簿を探しているのに、実際の戦士名簿は pc の棚にある状態です。

ただ「SaiyanWarrior の巻物を持ってきて」と言うだけでは、Javaは同じ棚の中を探します。

別の棚にあるなら、
pc の棚にある SaiyanWarrior の巻物
と住所つきで伝える必要があります。

まずは失敗する例を見てみる

まず、異なるパッケージのクラスを、そのままクラス名だけで使おうとして失敗する例を見ます。

Sample4.java は pb パッケージに属しています。
一方、使いたい SaiyanWarrior.java は pc パッケージに属しています。

この状態で、Sample4.java の中に SaiyanWarrior とだけ書くと、Javaは pb パッケージ内の SaiyanWarrior を探そうとします。

しかし、SaiyanWarrior は pc パッケージにあるため、見つけられません。

ファイル名:Sample4.java

package pb;

class Sample4
{
    public static void main(String[] args)
    {
        SaiyanWarrior warrior1 = new SaiyanWarrior();
        warrior1.show();
    }
}

ファイル名:SaiyanWarrior.java

package pc;

// サイヤ人戦士クラス
public class SaiyanWarrior
{
    private String name;
    private String style;

    public SaiyanWarrior()
    {
        name = "未登録";
        style = "流派未設定";
        System.out.println("サイヤ人戦士を作成しました。");
    }

    public void setWarrior(String n, String s)
    {
        name = n;
        style = s;
        System.out.println("戦士名を" + name + "、流派を" + style + "にしました。");
    }

    public void show()
    {
        System.out.println("戦士名は" + name + "です。");
        System.out.println("流派は" + style + "です。");
    }
}

Sample4.java がコンパイルできない理由

作業中フォルダを C:\Java\13 として、次のようにコンパイルします。

PS C:\Java\13>javac pb\Sample4.java

すると、SaiyanWarrior が見つからないというエラーになります。

pb\Sample4.java:7: エラー: シンボルを見つけられません
        SaiyanWarrior warrior1 = new SaiyanWarrior();
        ^
  シンボル:   クラス SaiyanWarrior
  場所: クラス Sample4
pb\Sample4.java:7: エラー: シンボルを見つけられません
        SaiyanWarrior warrior1 = new SaiyanWarrior();
                                     ^
  シンボル:   クラス SaiyanWarrior
  場所: クラス Sample4
エラー2個

Sample4.java が pb パッケージに属しているため、SaiyanWarrior とだけ書くと、Javaはまず pb パッケージ内の SaiyanWarrior を探します。

しかし、実際の SaiyanWarrior クラスは pc パッケージにあります。

Sample4 の書き方Javaの判断
SaiyanWarriorpb パッケージ内の SaiyanWarrior だと考える
new SaiyanWarrior()pb パッケージ内の SaiyanWarrior を作ろうとする
結果pb に SaiyanWarrior がないためエラー

ここが、同じパッケージのクラスを使う場合との大きな違いです。

図:別パッケージのクラスは住所つきで指定する

この図が示していること

この図では、pb パッケージの Sample4.java から、pc パッケージの SaiyanWarrior を使おうとしたときの失敗理由を表しています。

Sample4.java の中で SaiyanWarrior とだけ書くと、Javaはまず同じ pb パッケージ内を探します。

しかし、SaiyanWarrior は pc パッケージにあるため、pb の中では見つかりません。

書き方Javaが探す場所
SaiyanWarriorpb パッケージ
pc.SaiyanWarriorpc パッケージ

この図から分かることは、異なるパッケージのクラスを使うときは、どのパッケージにあるクラスなのかを住所つきで示す必要があるということです。

1つのファイルを異なるパッケージには分けられない

ここで、あわせて大切なルールがあります。

1つのソースファイルの中に、異なるパッケージに属するクラスを混在させることはできません。

理由は、1つのソースファイルには package 文を1つだけ書くからです。

たとえば、次のような書き方はできません。

// これはできない
package pb;

class Sample4
{
}

package pc;

class SaiyanWarrior
{
}

1つのファイルの先頭に書いた package 文は、そのファイル内のクラスの所属を決めます。

項目内容
package 文の数1つのソースファイルに1つだけ
1つのファイルに含まれるクラス基本的に同じパッケージに属する
異なるパッケージにしたい場合ファイルを分ける必要がある

ドラゴンボール風にたとえると、1本の巻物に「この巻物は pb の棚に置く」と書いたあと、途中から「ここから先は pc の棚に置く」と切り替えることはできない、ということです。

異なる棚に置きたいなら、巻物自体を分ける必要があります。

異なるパッケージのクラスを使うための条件

異なるパッケージのクラスを正しく使うには、主に2つの条件があります。

条件内容
1利用されるクラスを public にする
2利用する側で パッケージ名.クラス名 と書く

今回なら、pc パッケージの SaiyanWarrior クラスを、pb パッケージの Sample5 から使いたいわけです。

そのため、SaiyanWarrior クラスは public にします。

public class SaiyanWarrior

そして、Sample5 側では、SaiyanWarrior ではなく pc.SaiyanWarrior と書きます。

pc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();

このように書くことで、Javaは pc パッケージにある SaiyanWarrior クラスを使うのだと判断できます。

public は別パッケージから使えるようにする指定

クラスの前に public を付けると、そのクラスは別のパッケージからも利用できるクラスになります。

反対に、public を付けないクラスは、基本的に同じパッケージの中からしか使えません。

クラスの指定利用できる範囲
無指定同じパッケージ内から利用できる
public異なるパッケージからも利用できる

ドラゴンボール風にたとえると、public は「他の部署からも閲覧可能な巻物」にする指定です。

同じ棚の仲間だけで使う巻物なら、public でなくてもよい場合があります。

しかし、pb パッケージから pc パッケージの SaiyanWarrior を使いたいなら、SaiyanWarrior は外部に公開されている必要があります。

パッケージ名.クラス名で場所を明示する

異なるパッケージのクラスを使う側では、クラス名だけでなく、パッケージ名も含めて書きます。

今回なら、pc パッケージにある SaiyanWarrior クラスを使うので、次のように書きます。

pc.SaiyanWarrior

これは、pc パッケージの SaiyanWarrior クラスという意味です。

書き方意味
SaiyanWarrior同じパッケージ内の SaiyanWarrior として探しやすい
pc.SaiyanWarriorpc パッケージにある SaiyanWarrior を指定する

この書き方を使えば、別パッケージにあるクラスでも、場所をはっきり示して利用できます。

ドラゴンボール風にたとえると、単に SaiyanWarrior の巻物と言うのではなく、pc の棚にある SaiyanWarrior の巻物と指定するようなものです。

正しく使う例

次に、異なるパッケージのクラスを正しく使う例を見ます。

Sample5.java は pb パッケージに属しています。
SaiyanWarrior.java は pc パッケージに属しています。

Sample5 から pc の SaiyanWarrior を使うため、pc.SaiyanWarrior と書きます。

ファイル名:Sample5.java

package pb;

class Sample5
{
    public static void main(String[] args)
    {
        pc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();
        warrior1.show();
    }
}

ファイル名:SaiyanWarrior.java

package pc;

// サイヤ人戦士クラス
public class SaiyanWarrior
{
    private String name;
    private String style;

    public SaiyanWarrior()
    {
        name = "未登録";
        style = "流派未設定";
        System.out.println("サイヤ人戦士を作成しました。");
    }

    public void setWarrior(String n, String s)
    {
        name = n;
        style = s;
        System.out.println("戦士名を" + name + "、流派を" + style + "にしました。");
    }

    public void show()
    {
        System.out.println("戦士名は" + name + "です。");
        System.out.println("流派は" + style + "です。");
    }
}

Sample5.java が正しく動く理由

Sample5.java の中心は、次の1行です。

pc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();

この1行では、型として使う SaiyanWarrior も、new で作成する SaiyanWarrior も、どちらも pc パッケージにあるものだと指定しています。

部分意味
pc.SaiyanWarrior warrior1warrior1 は pc パッケージの SaiyanWarrior 型
new pc.SaiyanWarrior()pc パッケージの SaiyanWarrior オブジェクトを作成

そのため、pb パッケージにいる Sample5 からでも、pc パッケージの SaiyanWarrior を使えるようになります。

さらに、SaiyanWarrior クラスは public です。

public class SaiyanWarrior

このため、別パッケージである pb からも利用できます。

条件Sample5 で満たしている内容
利用されるクラスが publicpublic class SaiyanWarrior
利用する側が場所を明示pc.SaiyanWarrior と書いている

この2つがそろっているので、Sample5 は正しくコンパイルして実行できます。

実行結果

SaiyanWarrior クラスのコンストラクタでは、サイヤ人戦士を作成したことを表示します。

その後、show() で初期値を表示します。

サイヤ人戦士を作成しました。
戦士名は未登録です。
流派は流派未設定です。

表示内容としてはシンプルです。

しかし、大切なのは、pb パッケージの Sample5 から、pc パッケージの SaiyanWarrior を利用できていることです。

実行された処理内容
new pc.SaiyanWarrior()pc パッケージの SaiyanWarrior を作成
warrior1.show()作成したオブジェクトの情報を表示

異なるパッケージにあるクラスでも、正しい書き方をすれば、オブジェクトを作成し、メソッドを呼び出せます。

Sample4.java と Sample5.java の違い

Sample4.java と Sample5.java の違いを整理すると、今回の大切なポイントが見えやすくなります。

項目Sample4.javaSample5.java
所属パッケージpbpb
使いたいクラスpc の SaiyanWarriorpc の SaiyanWarrior
書き方SaiyanWarriorpc.SaiyanWarrior
利用先の明示していないしている
コンパイル失敗する成功する
理由pb の中の SaiyanWarrior として探してしまうpc の SaiyanWarrior と明示している

Sample4.java は、SaiyanWarrior とだけ書いています。

そのため、Javaは pb パッケージの中に SaiyanWarrior があるものとして探します。

一方、Sample5.java は pc.SaiyanWarrior と書いています。

そのため、Javaは pc パッケージの SaiyanWarrior を使うのだと分かります。

この違いが、異なるパッケージのクラスを使うときの中心です。

図:失敗例と成功例の違い

この図が示していること

この図では、異なるパッケージのクラスを使うときの失敗例と成功例を比較しています。

左側の Sample4.java では、pb パッケージの中で SaiyanWarrior とだけ書いています。
そのため、Javaは pb パッケージ内の SaiyanWarrior を探します。

しかし、SaiyanWarrior は pc パッケージにあるため見つからず、コンパイルエラーになります。

右側の Sample5.java では、pc.SaiyanWarrior と書いています。
これにより、Javaは pc パッケージの SaiyanWarrior クラスを使うのだと分かります。

さらに、SaiyanWarrior クラスは public になっているため、pb パッケージから利用できます。

比較Sample4.javaSample5.java
書き方SaiyanWarriorpc.SaiyanWarrior
クラスの場所明示していないpc パッケージと明示している
結果見つからない正しく使える

この図から分かることは、異なるパッケージのクラスを使うには、住所つきで指定する必要があるということです。

フォルダ構成

今回のファイルは、pb パッケージと pc パッケージに分かれます。

作業中フォルダが C:\Java\13 の場合、次のような構成になります。

C:\Java\13
        ├─ pb
        │  ├─ Sample4.java
        │  └─ Sample5.java
        └─ pc
           └─ SaiyanWarrior.java
フォルダパッケージ入るファイル
pbpbSample4.java、Sample5.java
pcpcSaiyanWarrior.java

package pb; と書いたファイルは pb フォルダへ置きます。
package pc; と書いたファイルは pc フォルダへ置きます。

ドラゴンボール風にたとえると、pb の札が付いた巻物は pb の棚へ、pc の札が付いた巻物は pc の棚へ置くということです。

コンパイルのしかた

正しく動く Sample5.java をコンパイルする場合、作業中フォルダ C:\Java\13 から次のように実行します。

PS C:\Java\13>javac pb\Sample5.java

Sample5.java の中では pc.SaiyanWarrior を使っています。

pc.SaiyanWarrior warrior1 = new pc.SaiyanWarrior();

そのため、pc フォルダの中に SaiyanWarrior.java が正しくあり、SaiyanWarrior クラスが public であれば、必要に応じて一緒にコンパイルされます。

コンパイル後は、次のように class ファイルができます。

C:\Java\13
        ├─ pb
        │  ├─ Sample4.java
        │  ├─ Sample5.java
        │  └─ Sample5.class
        └─ pc
           ├─ SaiyanWarrior.java
           └─ SaiyanWarrior.class
ソースファイルclass ファイル
pb\Sample5.javapb\Sample5.class
pc\SaiyanWarrior.javapc\SaiyanWarrior.class

実行のしかた

実行するときも、作業中フォルダ C:\Java\13 から行います。

Sample5 クラスは pb パッケージに属しています。

そのため、次のようにパッケージ名.クラス名で指定します。

PS C:\Java\13>java pb.Sample5
コマンド意味
java pb.Sample5pb パッケージの Sample5 クラスを実行する

ここで java Sample5 ではありません。

Sample5 は pb パッケージの中にあるので、pb.Sample5 と住所つきで指定します。

実行時には、pb.Sample5 が使う pc.SaiyanWarrior も必要です。
そのため、pc\SaiyanWarrior.class も正しく存在している必要があります。

public クラスのファイル名ルール

異なるパッケージから使われるクラスには public が必要です。

ただし、public クラスには大切なルールがあります。

ルール内容
public クラスは1ファイルに1つだけ1つの .java ファイルに複数の public クラスは書けない
ファイル名は public クラス名と同じpublic class SaiyanWarrior なら SaiyanWarrior.java

今回の SaiyanWarrior クラスは public です。

public class SaiyanWarrior

そのため、ファイル名は SaiyanWarrior.java にします。

SaiyanWarrior.java

ここが合っていないと、コンパイル時にエラーになります。

ドラゴンボール風にたとえると、外部にも公開する重要な巻物には、表紙の名前と中身の名前を一致させる必要がある、というイメージです。

修飾子の意味も整理しておく

異なるパッケージのクラスを使うときは、public の意味がとても大切です。

まず、クラスやインターフェイスに付ける指定を整理します。

クラス・インターフェイスの指定意味
無指定同じパッケージからのみ利用できる
public異なるパッケージからも利用できる

今回の中心は、クラスに付ける public です。

pc パッケージの SaiyanWarrior を pb パッケージから使うためには、SaiyanWarrior クラスが public である必要があります。

次に、フィールド、メソッド、コンストラクタに付ける修飾子も整理しておきます。

メンバ・コンストラクタの修飾子意味
private同じクラス内でのみアクセスできる
無指定同じパッケージからのみアクセスできる
protected同じパッケージ、または別パッケージのサブクラスからアクセスできる
publicすべてのクラスからアクセスできる

SaiyanWarrior クラスでは、フィールドは private にしています。

private String name;
private String style;

これは、name や style を外部から直接触らせないためです。

一方、コンストラクタ、setWarrior()、show() は public です。

public SaiyanWarrior()
public void setWarrior(String n, String s)
public void show()

これにより、別パッケージの Sample5 からでも、SaiyanWarrior オブジェクトを作成し、メソッドを呼び出せます。

SaiyanWarrior の要素修飾子役割
nameprivate外部から直接変更させない
styleprivate外部から直接変更させない
SaiyanWarrior()public別パッケージからオブジェクトを作れる
setWarrior()public別パッケージから情報を設定できる
show()public別パッケージから情報を表示できる

図:pb パッケージから pc パッケージのクラスを使う流れ

この図が示していること

この図では、pb パッケージの Sample5.java から、pc パッケージの SaiyanWarrior.java を使う流れを表しています。

左側の pb パッケージには Sample5.java があります。
Sample5.java の中では、pc.SaiyanWarrior と書いています。

右側の pc パッケージには SaiyanWarrior.java があります。
SaiyanWarrior クラスは public なので、別パッケージである pb からも利用できます。

役割クラス所属
実行するクラスSample5pb
利用されるクラスSaiyanWarriorpc

コンパイルは作業中フォルダから次のように行います。

C:\Java\13>javac pb\Sample5.java

実行は、main メソッドを持つ Sample5 をパッケージ名付きで指定します。

C:\Java\13>java pb.Sample5

この図から分かることは、実行するクラスと利用されるクラスが別パッケージにあっても、パッケージ名を正しく示せば連携できるということです。

パッケージ名で同名クラスを区別できる

パッケージの大きな利点は、同じクラス名でも、パッケージが違えば別のクラスとして扱えることです。

たとえば、次のようなクラスがあるとします。

指定意味
pa.SaiyanWarriorpa パッケージの SaiyanWarrior クラス
pc.SaiyanWarriorpc パッケージの SaiyanWarrior クラス

どちらもクラス名は SaiyanWarrior です。

しかし、所属するパッケージが違うため、Javaでは別のクラスとして区別されます。

ドラゴンボール風にたとえると、同じ SaiyanWarrior という名前の巻物でも、pa の棚にあるものと pc の棚にあるものは別物として扱えるということです。

この仕組みがあるおかげで、大きな開発でも名前の衝突を避けやすくなります。

名前空間とは何か

パッケージは、名前空間としても働きます。

名前空間とは、同じ名前がぶつからないように、名前をグループごとに管理するしくみです。

SaiyanWarrior というクラス名だけで見ると、同名クラスが増えたときに混乱します。

しかし、パッケージ名まで含めると、区別できます。

名前区別のしかた
SaiyanWarriorクラス名だけなので衝突しやすい
pa.SaiyanWarriorpa パッケージの SaiyanWarrior
pc.SaiyanWarriorpc パッケージの SaiyanWarrior
mission.SaiyanWarriormission パッケージの SaiyanWarrior

つまり、パッケージは単なるフォルダ分けではありません。

クラス名を整理し、同じ名前のクラスがあっても区別できるようにする仕組みでもあります。

ドラゴンボール風に言えば、巻物の名前だけでなく、どの棚の巻物かまで含めて管理することで、取り違えを防いでいるわけです。

パッケージ名の付け方

実際の開発では、パッケージ名は自由に決められます。

ただし、他の開発者や組織と名前がぶつかりにくいように、組織のドメイン名を逆順にした形がよく使われます。

たとえば、ドメインが xxx.co.jp の組織なら、次のような形です。

jp.co.xxx

さらに、機能ごとに続けることもあります。

jp.co.xxx.battle
jp.co.xxx.character
jp.co.xxx.training
パッケージ名役割の例
jp.co.xxx.battle戦闘処理
jp.co.xxx.characterキャラクター管理
jp.co.xxx.training修行メニュー管理

ドラゴンボール風にたとえると、戦士管理本部の大きな住所の下に、戦闘部門、戦士管理部門、修行部門の棚を作っていくようなイメージです。

学習段階では pa、pb、pc のような短い名前でも十分です。

ただし、実務では名前の衝突を避けるために、より具体的なパッケージ名を付けることが多くなります。

学習の最初につまずきやすいところ

異なるパッケージのクラスを使うときは、次のような点でつまずきやすいです。

つまずきやすい点理解のポイント
別パッケージでもクラス名だけで使えると思ってしまう異なるパッケージでは場所を明示する必要がある
public の意味があいまいpublic クラスは外部パッケージから利用できる
ファイル名のルールを忘れやすいpublic クラス名とファイル名は同じにする
同名クラスは使えないと思ってしまうパッケージ名が違えば別クラスとして共存できる
実行方法で迷うjava pb.Sample5 のようにパッケージ名付きで実行する

特に大切なのは、クラス名だけで探す場合と、パッケージ名付きで探す場合の違いです。

書き方意味
SaiyanWarrior同じパッケージ内の SaiyanWarrior として探す
pc.SaiyanWarriorpc パッケージの SaiyanWarrior を指定する

この違いが分かると、Sample4.java が失敗し、Sample5.java が成功する理由がはっきり見えてきます。

import の学習につながる大切な土台

今回の内容では、異なるパッケージのクラスを使うために、pc.SaiyanWarrior のようにパッケージ名.クラス名で書きました。

この書き方は、どのクラスを使っているのかがとても明確です。

ただし、何度も pc.SaiyanWarrior と書くと、コードが少し長くなることがあります。

そこで、次に import を学ぶと、別パッケージのクラスをより短い名前で使えるようになります。

書き方特徴
pc.SaiyanWarriorパッケージ名まで明示するので分かりやすい
import pc.SaiyanWarrior;先に宣言しておくと SaiyanWarrior と短く書ける

まずは、異なるパッケージのクラスを使うには、public と パッケージ名.クラス名 が必要だと理解することが大切です。

この土台があると、import の意味も自然につながります。

異なるパッケージのクラスを使うときの大事な感覚

異なるパッケージのクラスを使うときは、次のように考えると分かりやすいです。

考え方内容
別パッケージは別の棚同じ棚のようにクラス名だけでは探せない
public は外部公開他のパッケージから使えるようにする
パッケージ名.クラス名は住所どの棚のどのクラスかを示す
実行時も住所が必要java pb.Sample5 のように指定する
パッケージ名は名前空間同じクラス名でも区別できる

ドラゴンボール風にたとえると、pb の出撃指令書が、pc の戦士名簿を参照するようなものです。

そのためには、pc の戦士名簿が外部に公開されていて、さらに pc の棚にある SaiyanWarrior と住所つきで指定する必要があります。

この感覚がつかめると、Javaのパッケージ機能はかなり実践的に理解できるようになります。