内部クラス1
ネストトップレベルクラス
Javaの高度なトピックの一つとして、内部クラスの存在があります
JDK1.0では、私たちがこれまで使ってきたようなトップクラスと呼ばれるクラスしかありません
しかし、JDK1.1以降ならば内部クラスと呼ばれるクラスを生成することができます
内部クラスとは、クラスやメソッドのスコープ内に存在するクラスです
今回はそのうちの一つネストトップレベルクラスを学習しましょう
ネストトップレベルクラスとは、ネストされてはいるが機能はトップクラスと同じクラスのことです
アクセスする時に、トップクラスの名前を記述しなければいけないのが特徴です
Top.Nest obj = new Top.Nest();
上はコンストラクタへのアクセスとインスタンス化の方法の一例ですが
TopがトップクラスでNestがネストトップクラスの(つまり、内部クラス)指定です
ネストトップクラスの作成には、必ずクラス修飾子でstaticを指定することです
staticと宣言された内部クラスは、内部クラスとしてではなくトップクラスとして機能します
class test {
public static void main(String args[]) {
test.Kitty obj = new test.Kitty();
obj.write();
}
static class Kitty {
void write() {
System.out.println("Kitty on your lap");
}
}
}
名前の指定方法は内部クラスですが、その機能は同一クラス内でもトップクラスとして扱われています
トップクラスとの違いは名前の指定が入れ子になるというだけです
これをコンパイルすると test$Kitty.class というクラスファイルが生成されています
このクラスファイルこそが、ネストされたKittyクラスのクラスファイルです
$によって、このクラスがtestクラスにネストされているクラスであることがわかりますね
当然、内部クラスに他のクラスからアクセスすることも可能です
class test {
public static void main(String args[]) {
System.out.println(top.Kitty.str);
}
}
class top {
static class Kitty {
public static final String str = "Kitty on your lap";
}
}
ネストトップクラスの用途としては、他のクラスとの関係とデータ構造の簡易化にある
他のクラスに関係するクラス内部で用いるなどの用途が考えられます
内部クラスはクラスでもありメンバでもあるので
通常のメンバ同様に、privateやprotectedなどを指定することも可能です
class test {
public static void main(String args[]) {
//top.Kitty obj = new top.Kitty();
//↑を実行するとコンパイルエラー
top obj = new top();
obj.run();
}
}
class top {
void run() {
top.Kitty obj = new top.Kitty();
obj.write();
}
private static class Kitty {
void write() {
System.out.println("Kitty on your lap");
}
}
}
この結果を見ればわかると思いますが
内部クラスの修飾子は、外側のクラス(この場ではtopクラス)には通用しません
普段のメンバ同様に、外部のクラスに対して影響されます
内部クラスの入れ子は1段階に終わりませんが
通常多重のネスティングは行われません(あまり意味がない)
しかし、非常に構造的実体を持ち他のクラスとも関係している状態で
独立性の高いモジュールの生成などにおいて、まれに使われるようなこともあるかもしれません
class test {
public static void main(String args[]) {
top obj = new top();
obj.run();
}
}
class top {
void run() {
top.Kitty obj = new top.Kitty();
obj.write();
}
private static class Kitty {
void write() {
System.out.println("Kitty on your lap");
top.Kitty.Sakura obj = new top.Kitty.Sakura();
obj.write();
}
private static class Sakura {
void write() {
System.out.println("Card Captor Sakura");
}
}
}
}
ただし、Sakuraクラスへのアクセス権はtopクラスも持っていることに注意してください
内部クラスはprivateにすることで、外部クラスとの結合度は低下しますが
外側のクラスとの結合度は変わりません
上のプログラムの場合、topクラスのrun()メソッドからアクセスすることもできるのです
void run() {
top.Kitty obj1 = new top.Kitty();
obj1.write();
top.Kitty.Sakura obj2 = new top.Kitty.Sakura();
obj2.write();
}
このように、内部クラスはモジュールの開発に力を発揮します
外部クラスやトップクラスとの関係に注意して開発してください
因みに、内部クラスのトップクラスからであれば
トップクラスのシンボルを省略することが可能です
class test {
public static void main(String args[]) {
Kitty obj = new Kitty();
}
static class Kitty {
void wirte() {
System.out.println("Kitty on your lap");
}
}
}