例えばWindowsのフォルダをイメージしてください。Windowsにフォルダがなく、数千、数万というファイルが1箇所にあったら、ファイルを管理するのは大変です。フォルダのおかげでファイルをまとめることができます。
パッケージも同じ効果があります。パッケージはクラスをフォルダ(ディレクトリ)にまとめることで実現しているので当然です。
また、パッケージを使うと同じクラス名による衝突を避けることができます。Windowsのファイルもフォルダが違えば同じファイル名でも保存することができますよね。
Javaは他の人が作ったクラスを再利用しやすいというメリットがありますが、同じクラス名が付けられる可能性は大きいです。そこでインターネットのドメイン名をパッケージ名として使うことで、世界で唯一の名前が重複しないクラスを作ることができます。
Javaのクラスでパッケージを使う時は、パッケージの指定方法、ソースコードのコンパイル、プログラムの実行などが、これまでと少し変わりますので解説します。
【1】sample09 フォルダをフォルダごとコピーして、sample10 フォルダを作ります。
*sample10 フォルダ内にコピーされたクラスファイルは削除して、ソースファイルだけにしてください。
【2】sample10 フォルダの中に net フォルダを新規作成します。
【3】net フォルダの中に pgtop フォルダを新規作成します。
【4】pgtop フォルダの中に test フォルダを新規作成します。
【5】test フォルダの中に、 sample10 フォルダ内にあった Person.java と PersonTest.java を 移動します。
【6】test フォルダの Person.java と PersonTest.java を以下のように変更します。
*「\」はWindowsではエンマークのことです。
保存先 C:\java\sample10\net\pgtop\test
ファイル名 Person.java
package net.pgtop.test;
public class Person {
private String name;
private int age;
private String address;
public Person(String _name, int _age, String _address) {
name = _name;
age = _age;
address = _address;
}
public void say(){
System.out.println("私の名前は" + name + "です。年齢は"
+ age + "才で、住所は" + address + "です。");
}
public void setName(String _name){
name = _name;
}
public void setAge(int _age){
if (_age > 0) {
age = _age;
}else{
age = 0;
}
}
public void setAddress(String _address){
address = _address;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String getAddress(){
return address;
}
}
保存先 C:\java\sample10\net\pgtop\test
ファイル名 PersonTest.java
package net.pgtop.test;
public class PersonTest {
public static void main(String[] args) {
Person[] people = new Person[2];
people[0] = new Person("太郎", 21, "東京都港区");
people[1] = new Person("花子", 18, "北海道札幌市");
System.out.println("----- say()メソッドで表示");
for(int i = 0; i < people.length; i++){
people[i].say();
}
//セッターでデータを設定
people[0].setName("次郎");
people[0].setAge(-15);
people[0].setAddress("福岡県福岡市");
people[1].setName("桃子");
people[1].setAge(-25);
people[1].setAddress("宮城県仙台市");
System.out.println();
System.out.println("-----ゲッターでデータを取得して表示");
for(int i = 0; i < people.length; i++){
System.out.println(people[i].getName() + " "
+ people[i].getAge() + " " + people[i].getAddress() );
}
}
}
【7】コマンドプロンプトを起動して、カレントディレクトリを sample10 に切り替えます。
【8】javac net\pgtop\test\PersonTest.java と入力し、コンパイルします。
コンパイルが成功すると test フォルダの中にクラスファイルが作成されます。
【9】java net.pgtop.test.PersonTest と入力し、プログラムを実行します。
【10】プログラムの実行結果が表示されました。
【解説】
(1)パッケージの役割
・関連のあるクラスをまとめる。
・同じクラス名による衝突を避ける。
(2)インターネットのドメイン名をパッケージ名として使うには、ドメイン名を逆にして階層構造にする規則があります。
例えば私は、 http://pgtop.net/ とういホームページを運営するために、「pgtop.net」というドメイン名を取得していますので、これを逆にすると、「net.pgtop」になります。
もともとドメイン名は世界で唯一のものですので、逆にしても世界で1つしかありません。つまり net.pgtop の後は自分が好きなように決めても世界で唯一となります。
あなたが便利なクラスを作り、インターネットで配布することもできます。パッケージ名にドメイン名を使うことで、利用者はクラス名の衝突を気にせず、安心してあなたのクラスを使うことができます。
(3)パッケージ名とフォルダの階層構造を一致させる
パッケージ名が決まったら、フォルダの階層構造をパッケージの通りに作り、その中にクラスを配置する必要があります。例えば今回の例では、
java net.pgtop.test というパッケージの中に PersonTest クラスを作りましたので、
net\pgtop\test\PersonTest.java という階層構造にします。
(4)パッケージの指定
ソースコードの最初に以下のように記述するだけで、パッケージの指定となります。
package net.pgtop.test;
(5)コンパイルする時に、カレントディレクトリは sample10 なのですが、 sample10 にはソースファイルがないので、ディレクトリを含めたファイル名で指定する必要があります。
javac net\pgtop\test\PersonTest.java
(6)プログラムを実行するときは、パッケージ名を含めたクラス名で指定する必要があります。
java net.pgtop.test.PersonTest
*コンパイルするときはファイル名なので「\」、実行時はクラス名なので「.」になっていることに注目してください。
(7)無名パッケージ
実は前回までのクラスはパッケージを指定していませんでしたが、その場合は「無名パッケージ」として処理されていたのです。Javaではクラス名の衝突を避けるために、パッケージ名を指定する方法が一般的です。