プログラミング自主学習 DAY55 ネストクラス
ネストクラス(Nested Class)
特定なクラスが一か所しか使われない場合、
そのクラスを、他のクラス内部に宣言します。
それをネストクラスと呼びます。
クラスのメンバーとして、宣言されたメンバークラス、
メソッド内部に宣言されたローカルクラスがあります。
https://sjh836.tistory.com/145
なぜネストクラスを組むか?
- クラス間の上下関係をわかりやすく表すためだ。
- カプセル化のためだ。
- 読みやすくなり、メインテナンスが簡単になるためだ。
メンバークラス
メンバーインスタンスクラス(Non-static Inner Class)
[public] class Outer{
[public][private]class Inner{
}
}
インスタンスクラスは、主にprivateクラスだ。
private
の場合、Class Outer内部でしか使用できない。
戦いで相手の技と技術を知れば、不利になるように
内部にあるインスタンスクラスを private
にすることで内部の情報を隠す。
インスタンスクラスのオブジェクトを生成するためには、外部クラスのオブジェクトを生成することか必修だ。
また、継承したクラスと異なり、外部クラスのオブジェクトの中にあるクラスでるため、
外部クラスのフィールドを使用することもできる。
public class Wizard {
private int mp=0;
private class Fantasy{
public void showFantasyStar(){
System.out.println("****************");
}
public void fantasyPower(){
mp = 100;
System.out.println("mp: " + mp);
}
}
String name;
Wizard(String name){
this.name = name;
System.out.println("魔法使い "+ name + "を生成しました。");
}
public void showFanatasy() {
if(mp>90){
Fantasy a = new Fantasy();
System.out.println("$$$$$$$$$$$$$$$$");
a.showFantasyStar();
mp = 0;
System.out.println("幻覚が消えました。");
}
}
}
public class RPG {
public static void main(String[] args) {
Wizard wiz = new Wizard("Harry Potter");
System.out.println();
wiz.fantasyPower();
wiz.showFanatasy();
}
}
魔法使い Harry Potterを生成しました。
mp: 100
$$$$$$$$$$$$$$$$
****************
幻覚が消えました。
メンバー静的クラス(Static Inner Class, Static Nested Class)
[public] class Outer{
[public][default]static class Inner{
}
}
staticを付けることで、class Outer
のメンバーになるため、外部では、Outer class
のオブジェクトを生成せずに、Class Inner
を使用することができる。
その目的で主に、メンバー静的クラスのアクセス修飾子は主には、public
と default
を使う。
ローカルクラス(Method Local Inner Class)
[public] class Outer{
public Outer(){
class Local{} //default
}
public void method(){
class Local{} //default
}
}
メンバークラスと比べ、クラスにアクセス修飾子とstatic
を付けることができない。
外部では、オブジェクトの生成もフィールドとメソッドを使用することすらできないためだ。
実務では、非同期処理のためにスレッドのオブジェクトを生成するために使われるようだ。
public class Outer {
void useLocal() {
//Local Class
class Local {
int field1 = 1;
static int field2 = 2;
Local(){
System.out.println("Local Constructor excuted");
}
void method1() {
System.out.println("Local-method1 excuted");
}
static void method2() {
System.out.println("Local-method2 excuted");
}
}
}
}
public class AExample {
public static void main(String[] args) {
Outer o = new Outer();
o.useLocal()();
}
}
Local Constructor excuted
Local-method1 excuted
Local-method2 excuted
また、メソッドを呼び出した後、消えるため、ローカルクラスの変数は実質的にfinal
と似ている。(Java 7以前はfinalを付けることが必修だったが、今は明示的に付ける必要はない。
public class A {
public void method1(int arg) { //final int arg
int var = 1; //final int var
class B{
void method2() {
System.out.println(arg);
System.out.println(var);
//arg = 2; compile error
//var = 2; compile error
}
}
B b = new B();
b.method2();
//arg = 3; compile error
//var = 3; compile error
}
}
this vs .this
class Outer{
class Inner{
class B{
class A{
メンバークラスのオブジェクトが自分のフィールド、メソッドを使用させるためには this
を作成し、外部クラスのフィールドとメソッドに接近させるためには
外部クラスの名前の後に .this を付ける。
outer.this
A.this
Discussion