「SJC-P インナークラス」の版間の差分
ナビゲーションに移動
検索に移動
(ページの作成:「==SJC-P クラス、インタフェース、列挙型を宣言== ===インナークラス=== ====「通常」のインナークラス ==== 以下のようなクラス…」) |
|||
| 1行目: | 1行目: | ||
| − | ==SJC-P クラス、インタフェース、列挙型を宣言== | + | ==[[SJC-P クラス、インタフェース、列挙型を宣言]]== |
===インナークラス=== | ===インナークラス=== | ||
====「通常」のインナークラス ==== | ====「通常」のインナークラス ==== | ||
2020年2月16日 (日) 04:31時点における最新版
目次
SJC-P クラス、インタフェース、列挙型を宣言
インナークラス
「通常」のインナークラス
以下のようなクラスではない
- 静的ネストクラス
- メソッドローカルなインナークラス
- 無名インナークラス
- 「通常」のインナークラスは、static宣言を持つことはできない(1)
- Outer クラスのメンバーを参照できる(2)
- Outer クラスの参照は クラス名.this で参照できる(3)
- Outer クラスのコード内からは、インナークラスを直接インスタンス化できる(4)
- Outer クラスのコード外から、インナークラスをインスタンス化するには、アウタークラスの参照が必要(5)
package innerclass;
/**
* 「通常」のインナークラス
* 以下のようなクラスではない
* ・静的ネストクラス
* ・メソッドローカルなインナークラス
* ・無名インナークラス
* @author Yagi Hiroto
*/
public class InnerClassTest1 {
private String outerName = "InnerClassTest1";
/**
* 「通常」のインナークラス
*/
class InnerClass {
// (1) 「通常」のインナークラスは、static宣言を持つことはできない
public /* static */ void printName() {
System.out.println("my name : InnerClass");
// (2) Outer クラスのメンバーを参照できる
System.out.println("outer name : " + outerName);
// (3) Outer クラスの参照は クラス名.this で参照できる
System.out.println("outer : " + InnerClassTest1.this);
}
}
/*
* Outer クラスのコード「内」から、インナークラスのインスタンスを生成する
*/
public void printInnerName() {
// (4) インナークラスを直接インスタンス化できる
InnerClass ic = new InnerClass();
ic.printName();
}
public static void main(String[] args) {
InnerClassTest1 me = new InnerClassTest1();
me.printInnerName();
InnerClassTest2 ic2 = new InnerClassTest2();
ic2.printOtherInnerName();
}
}
class InnerClassTest2 {
/*
* Outer クラスのコード「外」から、インナークラスのインスタンスを生成する
*/
public void printOtherInnerName() {
// (5) インナークラスのインスタンス化には、アウタークラスの参照が必要
InnerClassTest1.InnerClass ic
= new InnerClassTest1().new InnerClass();
ic.printName();
}
}
メソッドローカルなインナークラス
- Outerクラスのメンバにアクセス可能(1)
- ローカル変数にはアクセスできない(2)
- インナークラスはヒープに置かれるため、メソッドから抜けるとスタックにアクセスできなくなる
- final なローカル変数にはアクセスできる(3)
- メソッドを抜けても生存している(4)
package innerclass;
public class InnerClassTest3 {
private int memberInt = 123;
private Object obj;
public void testMethodLocalInnerClass() {
int localInt = 456;
final int finalInt = 789;
class MethodInner {
void printInt() {
// (1) Outerクラスのメンバにアクセス可能
System.out.println("Member :" + memberInt);
// (2) ローカル変数にはアクセスできない
// インナークラスはヒープに置かれるため、メソッドから抜けるとスタックにアクセスできなくなる
// System.out.println("Local :" + localInt);
// (3) final なローカル変数にはアクセスできる
System.out.println("Final :" + finalInt);
}
public String toString() {
return "MethodInner";
}
}
MethodInner mi = new MethodInner();
mi.printInt();
obj = mi;
}
public static void main(String[] args) {
InnerClassTest3 me = new InnerClassTest3();
me.testMethodLocalInnerClass();
// (4) メソッドを抜けても生存している
System.out.println(me.obj.toString());
}
}
無名インナークラス
- 無名インナークラスとしてサブクラス化(1)
- スーパークラスのメソッドをオーバーライド(2)
- 末尾はセミコロン(3)
package innerclass;
public class InnerClassTest4 {
public void testAnonymousInner() {
/*
* 無名インナークラス
* (1) 無名インナークラスとしてサブクラス化
*/
BaseClass bc = new BaseClass() {
// (2) スーパークラスのメソッドをオーバーライド
public String getName() {
return "AnonymousDerivClass";
}
}; // (3) 末尾はセミコロン
System.out.println(bc.getName());
}
public static void main(String[] args) {
(new InnerClassTest4()).testAnonymousInner();
}
}
class BaseClass {
public String getName() {
return "BaseClass";
}
}
無名インナークラス(インターフェース実装クラス)
- 無名インナークラスとしてインターフェースを実装(1)
- インターフェースのメソッドを実装(2)
- 末尾はセミコロン(3)
package innerclass;
public class InnerClassTest5 {
public void testAnonymousInner() {
/*
* 無名インナークラス
* (1) 無名インナークラスとしてインターフェースを実装
*/
InfBase ib = new InfBase() {
// (2) インターフェースのメソッドを実装
public String getName() {
return "AnonymousDerivClass";
}
}; // (3) 末尾はセミコロン
System.out.println(ib.getName());
}
public static void main(String[] args) {
(new InnerClassTest5()).testAnonymousInner();
}
}
interface InfBase {
String getName();
}
無名インナークラス(メソッド引数として使用)
- セミコロン不要(1)
- }); で終わる(2)
package innerclass;
public class InnerClassTest6 {
public void testParamAnonymousClass(InfBase2 base) {
System.out.println(base.getName());
}
public static void main(String[] args) {
InnerClassTest6 me = new InnerClassTest6();
me.testParamAnonymousClass(
/* メソッド引数として無名インナークラスを利用する */
new InfBase2() {
public String getName() {
return "Parameter AnonymousClass";
}
} // (1)セミコロン不要
); // (2) }); で終わる
}
}
interface InfBase2 {
String getName();
}
© 2006 矢木浩人