반응형
Local inner class
지역 내부 클래스는 블록 내부에서 정의된 클래스이다.
정의가 된 블록(메소드) 내부에서만 사용할 수 있고, 접근 수식어(public, protected, private)는 쓸 수 없다.
외부 클래스의 멤버 변수는 모두 사용 가능하다.
💻 예제 1
📝 소스 코드
- OuterClass { localMethod() { LocalClass } }
public class OuterClass {
private int a = 1; // OuterClass 클래스의 멤버 변수
public void localMethod() { // OuterClass 클래스의 멤버 메소드
int b = 10; // 메소드의 지역 변수
// b = 30; <- 컴파일 오류
class LocalClass { // 메소드 내부에서 정의된 Local inner class
private int c = 100;
public void displayNum() {
System.out.println("a = " + a); // 외부 클래스의 멤버 변수
System.out.println("b = " + b); // 내부 클래스와 동일 스코프 내의 지역 변수
System.out.println("c = " + c); // 내부 클래스의 멤버 변수
}
}
LocalClass loc = new LocalClass();
// b = 50; <- 컴파일 오류
loc.displayNum();
}
b가 초기화 된 이후에 b 값을 변경하려고 하면 변수 b가 사용될 때 컴파일 오류가 발생한다. 위 코드에서 살펴보면 b를 출력하려고 하는 곳에서 오류가 발생할 것이다.
오류 구문은 다음과 같다.
Local variable b defined in an enclosing scope must be final or effectively final
b 값을 변경하려고 하면 displayNum() 메소드에서 초기화된 10이 출력되어야 하는지, 나중에 바꾼 값인 50이 출력되어야 하는지 헷갈린다. 따라서 로컬 내부 클래스에서 사용 가능한 지역 변수는 반드시 한 번 초기화된 후 값이 변경되지 않아야 한다.
- Main
public class Main {
public static void main(String[] args) {
System.out.println("Local Inner Class (지역 내부 클래스)\n");
OuterClass out = new OuterClass();
out.localMethod();
}
}
📄 실행 결과
🧐 인터페이스와 다형성을 이용해 지역 클래스에 정의된 메소드 외부에서 사용하기
외부에서 사용하고 싶은 메소드를 선언한 인터페이스를 작성한다.
메소드의 반환 타입은 앞서 정의한 인터페이스 타입으로 정의한다.
로컬 클래스는 인터페이스를 구현(implements) 하도록 정의한다.
로컬 클래스의 인스턴스를 생성하고 반환하면 된다.
💻 예제 2
📝 소스 코드
- Person
public class Person {
private String name;
public Person(String name) {
this.name = name.;
}
public MyReadable createInstance(int age) {
class PersonWithAge implements MyReadable {
@Override
public void readInfo() {
System.out.println("이름 : " + name);
System.out.println("나이 : " + age);
}
}
MyReadable person = new PersonWithAge(); // 다형성 (자손 타입을 부모가 받으므로)
return person;
}
}
interface MyReadable {
public abstract void readInfo();
}
- Main
public class Main {
public static void main(String[] args) {
System.out.println("Local 내부 클래스의 활용\n");
Person person = new Person("홍길동");
MyReadable r = person.craeteInstance(20);
r.readInfo();
}
}
이와 같은 방식으로 사용하고 싶은 메소드 readInfo()를 포함하고 있는 MyReadable 인터페이스를 생성하고,
PersonWithAge(로컬 내부 클래스)에서 해당 인터페이스를 implements 하여 구현하면
지역 클래스에서 정의된 메소드(readInfo())를 사용할 수 있다.
📄 실행 결과
Inner class 개념
Member inner class 예제
Nested class(Static inner class) 예제
Anonymous class 예제
반응형