});クラスを使ったプログラムのメリットは、一度作ったクラスを再利用できることです。再利用できるのはプログラマ自身が作ったクラスだけではなく、他人が作ったクラスでも構いません。Javaを始めたばかりの皆さんは、「ほかの人が作ったクラスを利用する機会なんてあるのだろうか?」と思われるかもしれません。この連載の読者の皆さんはすでに他人が作ったクラスを再利用しています。そのクラスとは、String型のことです。String型はJavaというプログラム言語の仕様に組み込まれた極めて基本的なクラスですが、クラスである以上、String型というクラスの定義や、文字列を扱うためのメソッドを用意しなければなりません。String型のような基本のクラスは、Java言語を作った人たちによって作られました。Files\j2sdk1.4.1」にある「src.zip」という圧縮ファイルの中にあります。圧縮ファイルの中の「java/Lang」フォルダにある「String.java」というファイルです。圧縮ファイルの中からString.javaをデスクトップなどにドラッグ&ドロップし、エディタなどで開いてみてください。はじめにコメント文がありますが、以下のようなString型の定義があるはずです。これまでString型を何げなく使ってきましたが、この連載で定義したHTMLDocumentなどのクラス同様、メンバ変数やメソッドの定義が並んでいます。注:コメント文などを大幅に省略してあります。上記のメンバ変数やメソッドに付いているprivate、publicというキーワードの意味は前回「クラスのメンバに利用制限を付与するアクセス制御」で紹介したとおりです。簡単におさらいすると、privateを付けるとクラス内部の作業用になり、publicはこのクラスのインスタンスを生成したプログラムなど、外部から利用できる変数やメソッドになります。この連載において、これまでは単に文字列を操作するためのクラスとしてString型を使ってきましたが、String型の大きな特徴は一度設定した文字列は後から変更できない読み取り専用の型であることです。文字列はchar型配列のメンバ変数value[]に格納されます。value[]に格納された文字列の長さはint型のメンバ変数countに格納されます。value[]もcountもprivateに指定されていますので、クラスの外部からはアクセスできません。そこで、文字列の長さを調べるlength()のようなメソッドを使って間接的に文字列の長さを取得するわけです。別のいい方をすると、String型のソースコードを見たことのないプログラマは、length()がどのように文字列の長さを調べているのか分かりません。内部にcountというメンバ変数があって、length()は単にcountの値を返しているだけとは気付かないわけです。Javaのようなオブジェクト指向言語ではクラスを継承させることで元のクラスの機能を拡張できますが、サブクラスを定義するプログラマでさえ、スーパークラスがどのように定義されているのか、詳細を知る必要はありません。クラスという道具を使いこなすには、それぞれのクラスがどのような機能を持っているかを理解すればよく、その道具はどのようにできているのかは知らなくてよいのです。このことをオブジェクト指向の世界では「カプセル化」といいます。クラスの内部構造は隠してしまって、プログラマは公開されたメンバ変数やメソッドだけを使ってください、ということです。従って、何かのクラスについて知りたいプログラマは、クラスの定義ではなく、クラスのpublicなメンバ変数とメソッドとしてどんなものが用意されているのか調べればよいのです。カプセル化されているのだから、クラスの定義なんて知らなくていい、とは思わないでください。確かにプログラムを作るうえではクラスの定義を知っている必要はありません。Javaを作った人々が書いたソースコードを眺めることは、それだけで勉強になります。ソースコードを眺めることをきっかけに、初心者から中級者、中級者から上級者にステップアップすることもあると思います。クラスの説明をどんなに読んでも分からなかったことがソースコードを読んだら分かったということもよくあることです。パッケージとは?Javaが提供しているクラスや他人が作ったクラスを再利用する場合、クラスの名前に注意しなければなりません。String型のような基本的なクラス名と重複するようなクラスは作った方に責任がありますが、この連載で作成したHTMLDocumentのように、Javaの言語仕様には含まれないけれど、誰が作ってもいかにも同じ名前が付きそうなクラスはいくつもあります。そこでjavaには「パッケージ」という考え方があります。説明の前に実際にパッケージを作ってみましょう。省略}}パッケージの保存からコンパイルまでの手順は以下のとおりです。HTMLDocument.javaC:\DOCUME~1\MYDOCU~1\MYJAVA~1>\JP\CO\ATMARKIT\JAVA>次に、パッケージとして保存したHTMLDocumentを利用するプログラムを作成します。Applications\にPackageTest.javaの名前で保存してからコンパイルします。PackageTest.javaC:\DOCUME~1\MYDOCU~1\MYJAVA~1>\JP\CO\ATMARKIT\JAVA>何かを実行するプログラムではありませんので何も起こりませんが、PackageTest.javaにはHTMLDocumentの定義が含まれないのに、HTMLDocumentを利用できたことが分かります。それでは、はじめから順に説明していきます。jp.co.atmarkit.java」という文があります。「jp.co.atmarkit.java」全体がパッケージの名前になります。続いてクラスの宣言をしています。jp.co.atmarkit.java」というパッケージに所属する「HTMLDocument」というクラスという意味になります。次にPackageTest.javaとして保存したファイルをもう一度見てみましょう。jp.co.atmarkit.java.HTMLDocument;」という文があります。4行目に出てくるHTMLDocumentのクラス定義はPackageTest.javaに含まれませんが、コンパイルエラーになりません。はじめのimport文によって、コンパイラはHTMLDocumentが「jp\co\atmarkit\java\」にある「HTMLDocument.class」のことだと分かるからです。パッケージの名前とディレクトリ構造を一致させることで、コンパイラが目的の.classファイルを見つけ出せるようにしているわけです。クラス名が同じでも、パッケージ名が異なれば別のディレクトリに保存されることになりますので、同じクラス名でも共存できるわけです。パッケージ名とクラス名String型の話に戻りましょう。java.lang;」という文があります。java.lang;つまり、String型クラスも「java.lang」というパッケージに所属するクラスなのです。java.lang.String」などとしないでもString型を利用できました。してなのでしょうか?実はjava.langというパッケージにはString型や「System.out.println(...)」で登場したSystemのように、Javaの言語仕様そのものといえるクラスが所属しています。java.lang.String」などとしないでも利用できるようになっているのです。パッケージとクラスの関係では、もう1つ重要なことがあります。それは、正式なクラス名は常にパッケージとの組み合わせで表現されるということです。ソースファイルの中でこそ「String」のようにクラス名単独で登場しますが、あくまでも「java.lang.String」が正式なクラス名です。name)」と呼びます。分かりにくいので実例を示しましょう。Sample";}}単純名を使った上記のプログラムは、以下のように完全修飾名を使っても記述できます。Sample";}}クラス名を名前だとすると、パッケージ名は名字に相当すると考えればよいでしょう。パッケージはディレクトリ構造で管理されるので同じコンピュータ内で競合することはありません。コンパイラそのものは常にクラス名を完全修飾名で扱いますので、たとえクラス名が同じになることがあっても、パッケージ名は異なりますから、完全修飾名としては区別できるわけです。コンパイラがクラス名を完全修飾名で扱っていることは、コンパイラが生成する.classファイルをエディタで開くと分かります。以下は「単純名のサンプル」をコンパイルしたSimpleNameSample.classファイルです。サンプル」をコンパイルしたFullyQualifiedNameSample.classファイルは以下のようになります。!..................クラス名と文字列部分は違いますが、バイナリ部分や「java/lang/String」の部分は同じになっていることがわかります。コンパイラ内部で、クラス名は常に完全修飾名で扱われます。人間にとって完全修飾名は冗長です。そこでクラス名が重複しない限り、importだけで単純名で表記できるようにしているわけです。import文のクラス名は省略できます。java.utilに含まれるComparator、ArrayListというクラスを利用したいときに、以下のように記述できます。java.util.*;アスタリスクはクラス名の代わりに使えます。この場合は、「java.util」というパッケージに所属するクラスすべてを利用する、という意味になります。java.lang.*」という文が省略されている、とも考えられます。パッケージ名の命名方法パッケージが完全修飾名で表したときのクラス名の重複を防ぐ方法であることは分かったと思います。Javaで何かを開発しようと思ったら、1人の開発者が1台の閉じたコンピュータで作業するというわけにはいきません。Javaに含まれるさまざまなパッケージや、他人の作ったパッケージを購入して使う場合もあります。このとき、それぞれが勝手なパッケージ名を付けてしまったら、クラス名の重複を防ぐという機能を果たせなくなります。そこでJavaでは、パッケージ名として所属企業のドメイン名をトップレベルドメイン側から並べ替えてパッケージ名にする方法が推奨されています。はじめに紹介したsrc.zipの中身に、例えば「com/sun/corba」というディレクトリがありますが、これは「corba.sun.com」というドメイン名を逆さまにしたものです。co.jp」というドメイン名を逆さまにしたものです。すれば、たとえHTMLDocumentというクラス名を使うほかのパッケージがあったとしても、完全修飾名では区別できるわけです。皆さんが自作のパッケージを作る場合は、自社のドメイン名を使うとよいでしょう。次回は、String型のソースコードを詳しく見ながら、クラスの理解をさらに深めます。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。