(96.10.16更新)
---------------HelloWorld.java -----------------------
import java.awt.*;
//* java.awtパッケージにあるクラス(ここでは
//* GraphicsとComponent)を略称で利用できるようにする。
//*import文を書かなかった場合は、クラス定義の時に
//*public class HelloWorld extends java.applet.Applet {
//*と書く必要がある。
public class HelloWorld {
//* HelloWorldという名前のクラスを定義する。
//* public宣言によってこのクラスをパッケージ外にも公開する。
public void paint(Graphics g) {
//* メソッド定義。Graphichsクラスのpaintメソッドを起動する。
//* 実際に与えられる引数を『g』という名前で扱うと宣言する。
//* 返り値はないのでvoidとする。
g.drawString("Hello,World!",50,100);
//* gと呼ぶオブジェクトのdrawStringメソッドを、
//*"Hello,World!"、50、100という三つの引数を与えて呼び出す。
//* つまり"Hello,World!"という文字列を座標(50,100)に描かせる。
}
}
---------------------------------------------------
class HelloWorld {
static void main(String args[]) {
System.out.println("HelloWorld");
}
}
ここでSystem.out.println()は、newで実体を作っていないように見える。
しかし、java.lang.Systemクラスの定義を見ると、ちゃんと
out = new PrintStream(new BufferedOutputStream(...));
と実体を作っている。
この処理は、Systemクラスをロードする時に行われている。
また、static宣言されたフィールドはそれがインスタンスでなくクラスに保持
されるので、クラスが存在する時にはいつでもそれを参照することが出来る。
しかし、フィールドの中身が必ず入っているわけではない。
例えばSystem.outと参照することの出来るstaticフィールドには、PrintStream
クラスのインスタンスが入ることになっているが、実際はJavaの実行環境が起動し
た時にインスタンスを生成して保持するようになっている。
だから、このインスタンス生成がされる前にそのフィールドを参照すると、当然中
身はnullになっているが、Systemクラスが読み込まれるときに初期化作業が行わ
れるのでこれを参照できるタイミングは事実上存在しない。
クラスAとクラスBがあったとして、クラスAのなかからクラスBのメソッド
を使いたい場合は、以下のようになる。
例)
class B {
public void hoge_public() {
}
pprotected void hoge_protected() {
}
private void hoge_private() {
}
void hoge_nothing() {
}
}
class A {
B b = new B();
void foo() {
b.hoge_public(); // OK
b.hoge_protected(); // NG(※)
b.hoge_private(); // NG
b.hoge_nothing(); // OK
}
}
・ OKは使用できる。
・ NGはコンパイルでエラーになる。
(※)
クラスAがクラスBのサブクラスだったらOKとなる。
すなわち、
class A extends B {
:
}
別の視点から見ると、クラスAのインスタンスであるオブジェクトが
クラスBのオブジェクトを持っていることを表す。
ここで、「b」のことをクラスAの「インスタンス変数」という。
例えば、めだかクラスは色クラスのインスタンス変数を持っていた。
ところで、オブジェクトの階層には2種類あり、
『車 is-a 乗物』等の is-a階層(属と種の関係)と、
『車 has-a ドア』等のhas-a階層(全体と部分の関係)である。
このうち、インスタンス変数は、has-aの関係を表すのに使われる。