内部クラス
普通内部クラス
static変数、staticメソッドとstatic内部クラスが含めない
public class OutterClass {
private int mOut = 10;
private int mMem = 20;
public class InnerClass {
private int mIn = 0;
private int mMem = 30;
public void printOutPrivate() {
//外部クラスのprivate変数にアクセス
System.out.println(mOut);
//同じprivate変数を区別
System.out.println(OutterClass.this.mMem);
}
}
public void printInPrivate() {
InnerClass in = new InnerClass();
//内部クラスのprivate変数にアクセス
System.out.println(in.mIn);
}
public void printOutPrivate() {
InnerClass in = new InnerClass();
in.printOutPrivate();
}
public InnerClass newInnerClass() {
return new InnerClass();
}
public static void main(String[] args) {
OutterClass out = new OutterClass();
out.printInPrivate();
out.printOutPrivate();
//外部クラスのインスタンスが必要
OutterClass.InnerClass in = out.new InnerClass(); //方法1
OutterClass.InnerClass in = out.newInnerClass(); //方法2
in.printOutPrivate();
}
}
静的内部クラス
外部クラスがpackage名に相当する
public class OutterClass {
private int mOut = 10;
public static class InnerClass {
private int mIn = 0;
public void printOutPrivate() {
//外部クラスのprivate変数にアクセスできない
//System.out.println(mOut);
}
}
public void printInPrivate() {
InnerClass in = new InnerClass();
//内部クラスのprivate変数にアクセス
System.out.println(in.mIn);
}
public void printOutPrivate() {
InnerClass in = new InnerClass();
in.printOutPrivate();
}
public InnerClass newInnerClass() {
return new InnerClass();
}
public static void main(String[] args) {
//外部クラスのインスタンスが不要
OutterClass.InnerClass in = new InnerClass(); //方法1
OutterClass.InnerClass in = out.newInnerClass(); //方法2
in.printOutPrivate();
}
}
サンプル
public class Person {
private String name;
private Home home;
public Person(String name) {
this.name = name;
}
// getter/setter
public static class Home{
private String address;
private String tel;
public Home(String address, String tel) {
this.address = address;
this.tel = tel;
}
// getter/setter
}
}
Person p = new Person("Andy");
p.setHome(new Person.Home("Tokyo", "03-xxx"));
静的内部クラスと普通内部クラスの区別
1.静的内部クラスはstatic変数・メソッドのみをアクセスできる
2.普通内部クラスは外部クラスを依頼するが、静的内部クラスと外部クラスはそれぞれ独立
3.普通内部クラスはstatic変数・メソッドを宣言できない、静的内部クラスは制限なし
ローカル内部クラス
public class OutterClass {
public Hello testLocalInner() {
class LocalInner implements Hello {
@Override
public void print() {
//do something
}
}
return new LocalInner();
}
public static void main(String[] args) {
OutterClass out = new OutterClass();
Hello hello = out.testLocalInner();
hello.print();
}
}
匿名クラス
public class OutterClass {
private int field = 5;
public void print(final String param){
final int local = 10;
Hello hello = new Hello() {
@Override
public void print() {
System.out.println(local);
System.out.println(param);
System.out.println(field);
}
};
hello.print();
}
//戻り値の場合
public Hello testAnonymousInner() {
return new Hello() {
@Override
public void print() {
//do something
}
};
}
//引数の場合
public void testAnonymousInner2(Hello hello) {
hello.print();
}
public static void main(String[] args) {
OutterClass out = new OutterClass();
Hello hello = out.testAnonymousInner();
hello.print();
out.testAnonymousInner2(new Hello() {
@Override
public void print() {
//do something
}
});
}
}
List l = new ArrayList(){};
下記と同じ
class Sub extends ArrayList{
}
List l = new Sub();
List l = new ArrayList(){{}};
下記と同じ
class Sub extends ArrayList{
{
// 初期化
}
}
List l = new Sub();
※List l = new ArrayList(){{}{}{}};でもOK
サンプル
class Test{
private int i;
private int j;
public Test(){}
public Test(int i, int j){
this.i = i;
this.j = j;
}
protected void methodA(){
// do something
}
public int methodB(){
// do something
}
}
Test t = new Test(2, 3){
{
methodA();
}
};
t.methodB();
下記と同じ
class Sub extends Test{
{
methodA();
}
public Sub(int i, int j){
super(i, j);
}
}
Test t = new Sub(2, 3);
t.methodB();