내부 클래스
내부클래스는 클래스안에 클래스를 말한다. 내부클래스는 외부 클래스의 인스턴스가 생성되야만 접근이 가능하다. (static이 아닌경우)
내부클래스 예제
package innerclass;
class OutClass {
private int num = 10;
private static int sNum = 20;
private InClass inClass;
public OutClass() {
inClass = new InClass();
}
class InClass {
int inNum = 100;
void inTest() {
System.out.println("OutClass num =" + num + "(외부 클래스의 인스턴스 변수)");
System.out.println("OutClass num =" + sNum + "(외부 클래스의 인스턴스 변수)");
}
}
public void usingClass() {
inClass.inTest();
}
}
public class innerTest {
public static void main(String[] args) {
OutClass outClass = new OutClass();
System.out.println("외부 클래스 이용하여 내부 클래스 기능 호출");
outClass.usingClass();
}
}
- 외부클래스 인스턴스를 생성해야 내부클래스를 사용할 수 있다.
- 내부클래스에서 외부 클래스의 인스턴스 변수에 접근이 가능하다.
- 내부클래스에는 static 변수나 메서드를 사용할 수 없다.
- 인스턴스 내부에 있는 클래스는 외부 클래스의 메서드가 호출 될 때 사용할 수 있다.
OutClass.InClass inClass = outClass.new InClass();
System.out.println("외부 클래스 변수를 이용하여 내부 클래스 생성");
inClass.inTest();
- 위와 같은 방법으로 인스턴스 내부에 있는 클래스를 생성할 수 있음.
정적 내부 클래스
내부클래스를 static으로 선언하여 내부 변수와 메서드도 static 으로 접근 가능.
정적 내부클래스 선언 예제
package innerclass;
class OutClass {
private int num = 10;
private static int sNum = 20;
private InClass inClass;
public OutClass() {
inClass = new InClass();
}
class InClass {
int inNum = 100;
// static int sInNum = 200 // <---- 에러!
void inTest() {
System.out.println("OutClass num =" + num + "(외부 클래스의 인스턴스 변수)");
System.out.println("OutClass num =" + sNum + "(외부 클래스의 인스턴스 변수)");
}
}
public void usingClass() {
inClass.inTest();
}
static class InStaticClass {
int inNum = 100;
static int sInNum = 200;
void inTest() {
System.out.println("InStaticClass inNum =" + inNum + "(내부 클래스의 인스턴스 변수 사용)");
System.out.println("InStaticClass sInNum =" + sInNum + "(내부 클래스의 스태틱 변수 사용)");
System.out.println("InStaticClass inNum =" + sNum + "(외부 클래스의 스태틱 변수 사용)");
}
static void sTest() {
System.out.println("OutClass sNum = " + sNum + "(외부 클래스의 스태틱 변수 사용)");
System.out.println("InStaticClass sInNum = " + sInNum + "(내부 클래스의 스태틱 변수 사용)");
}
}
// public int getInNum() {
// return inClass.inNum;
// }
}
public class innerTest {
public static void main(String[] args) {
OutClass outClass = new OutClass();
System.out.println("외부 클래스 이용하여 내부 클래스 기능 호출");
outClass.usingClass();
System.out.println();
OutClass.InClass inClass = outClass.new InClass();
System.out.println("외부 클래스 변수를 이용하여 내부 클래스 생성");
inClass.inTest();
System.out.println();
OutClass.InStaticClass sInClass = new OutClass.InStaticClass();
System.out.println("정적 내부 클래스 일반 메서드 호출");
sInClass.inTest();
System.out.println();
System.out.println("정적 내부 클래스의 스태틱 메소드 호출");
OutClass.InStaticClass.sTest();
}
}
- 정적 내부클래스는 외부 인스턴스를 생성하지 않고 바로 생성할 수 있다. new OutClass.InStaticClass();
- 인스턴스 변수와 스태틱변수 & 메서드에 대해 유효범위가 다르므로, 주의가 필요하다.
지역내부클래스
메서드안에서 사용하는 클래스
LocalInnerTest.java
package innerclass;
class Outer {
int outNum = 100;
static int sNum = 200;
Runnable getRunnable(int i) {
int num = 100;
class MyRunnable implements Runnable {
int localNum = 10;
@Override
public void run() {
System.out.println("i=" + i); // 10
System.out.println("num=" + num); // 100
System.out.println("localNum=" + localNum); // 10
System.out.println("outNum=" + outNum + "(외부 클래스 인스턴스 변수)"); // 100
System.out.println("Outter.sNum=" + Outer.sNum + "(외부 클래스 정적 변수)"); // 200
}
}
return new MyRunnable();
}
}
public class LocalInnerTest {
public static void main(String[] args) {
Outer out = new Outer();
Runnable runner = out.getRunnable(10);
runner.run();
}
}
- 지역내부클래스에서 사용하는 지역변수는 모두 컴파일 과정에서 상수(final) 로 바뀐다.
- 그래서 getRunnable 메서드의 인자 i와 num 은 바꿀 수 없다.
익명내부클래스
AnonymousInnerTest.class
package innerclass;
class Outter {
// 방법1
Runnable getRunnable(int i) {
int num = 100;
return new Runnable() {
@Override
public void run() {
System.out.println(i);
System.out.println(num);
}
};
}
// 방법2
Runnable runner = new Runnable() {
@Override
public void run() {
System.out.println("Runnable이 구현된 익명 클래스 변수");
}
};
}
public class AnonymousInnerTest {
public static void main(String[] args) {
Outter out = new Outter();
Runnable runnerble = out.getRunnable(10);
runnerble.run();
out.runner.run();
}
}
- 지역내부클래스와 같은 기능을 익명내부클래스로 선언하였음.
출처: do it 자바프로그래밍