티스토리에 저장했던 글을 옮겼습니다.
https://mrcocoball.tistory.com/89
class OutClass {
// field
private int num = 10;
private static int sNum = 20;
private InClass inClass; // 내부 클래스 선언
// constructor
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 sNum = " + sNum + "(외부 클래스의 정적 변수)");
System.out.println("InClass inNum = " + inNum + "(내부 클래스의 인스턴스 변수)");
}
// static void sTest() { } // 에러 발생, 정적 메소드 사용 불가
}
public void usingClass() {
inClass.inTest(); // 내부 클래스 사용해서 메소드 호출
}
}
public class InnerTest_Instance {
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(); // 내부 클래스의 내부 인스턴스 메소드 사용
}
}
static class InStaticClass { // 정적 내부 클래스
int inNum = 100;
static int sInNum = 200;
void inTest() { // 정적 클래스의 일반 메소드
// num += 10; // 외부 클래스의 인스턴스 변수 사용 불가
System.out.println("InStaticClass inNum = " + inNum + "(내부 클래스의 인스턴스 변수 사용)");
System.out.println("InStaticClass sInNum = " + sInNum + "(내부 클래스의 정적 변수 사용)");
System.out.println("OutClass sNum = " + sNum + "(외부 클래스의 정적 변수 사용)");
}
static void sTest() { // 정적 클래스의 정적 메소드
// num += 10; // 외부 클래스의 인스턴스 변수 사용 불가
// inNum += 10; // 내부 클래스의 인스턴스 변수 사용 불가
System.out.println("OutClass sNum = " + sInNum + "(외부 클래스의 정적 변수 사용)");
System.out.println("InStaticClass sInNum = " + sNum + "(내부 클래스의 정적 변수 사용)");
}
}
}
public class InnerTest_Static {
public static void main(String[] args) {
// 외부 클래스 미생성 후 바로 정적 내부 클래스 생성
OutClass.InStaticClass sInClass = new OutClass.InStaticClass();
System.out.println("정적 내부 클래스 일반 메소드 호출");
sInClass.inTest();
System.out.println();
System.out.println("정적 내부 클래스의 정적 메소드 호출");
OutClass.InStaticClass.sTest();
OutClass outClass = new OutClass();
System.out.println("외부 클래스 이용하여 내부 클래스 기능 호출");
outClass.usingClass(); // 내부 클래스 기능 호출
System.out.println();
OutClass.InClass inClass = outClass.new InClass(); // 외부 클래스 이용, 내부 클래스 생성
System.out.println("외부 클래스 변수 이용, 내부 클래스 생성");
inClass.inTest(); // 내부 클래스의 내부 인스턴스 메소드 사용
}
}
class Outter {
// field
int outNum = 100;
static int sNum = 200;
// method
Runnable getRunnable(int i) { // Runnable 타입 return
int num = 100;
class MyRunnable implements Runnable { // Runnable을 구현
int localNum = 10;
@Override
public void run() {
// num = 200; // 에러 발생, 로컬 변수는 상수로 바뀜
// i = 100; // 에러 발생, 매개변수 역시 로컬 변수처럼 상수로 바뀜
System.out.println("i = " + i); // getRunnable 메소드의 매개변수 i를 받음
System.out.println("num = " + num); // getRunnable 메소드 내부 로컬 변수 100
System.out.println("localNum = " + localNum); // MyRunnable 클래스의 로컬 변수 10
System.out.println("outNum = " + outNum + "(외부 클래스 인스턴스 변수 사용)");
System.out.println("Outter.sNum = " + Outter.sNum + "(외부 클래스 정적 변수 사용)");
}
}
return new MyRunnable(); // MyRunnable() 호출
}
}
public class InnerTest_Local {
public static void main(String[] args) {
Outter out = new Outter(); // 외부 클래스 생성
Runnable runner = out.getRunnable(10); // Runnable 타입 runner = getRunnable 통해서 생성
runner.run(); // runner 통해서 run 호출
}
}
부모클래스 [필드 변수] = new 부모 클래스(매개값, ...) {
// 필드
// 메소드
};
인터페이스 [필드 변수] = new 인터페이스() {
// 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
// 필드
// 메소드
};
class Outter2 {
// method
Runnable getRunnable(int i) { // MyRunnable() 을 지우고 익명 내부 클래스화
int num = 100;
return new Runnable() { // 익명 자식 객체 생성
@Override
public void run() {
// num = 200; // 에러 발생
// i = 10; / 에러 발생
System.out.println(i);
System.out.println(num);
}
};
}
Runnable runner = new Runnable() { // 익명 자식 객체 생성
@Override
public void run() {
System.out.println("Runnable 이 구현된 익명 클래스 변수");
}
};
}
public class AnonymousInnerTest {
public static void main(String[] args) {
Outter2 out = new Outter2();
Runnable runnable = out.getRunnable(10);
runnable.run();
out.runner.run();
}
}