JAVA/JAVA
Java | Inner Class 내부 클래스 & Anonymous class 익명 클래스
pathas
2020. 2. 4. 17:25
Inner Class 내부 클래스
클래스 내부에 작성하는 클래스
- 내부 클래스는 외부 클래스의 접근 제어자에 상관 없이 멤버변수, 메소드에 접근 가능
- 외부 클래스에서 내부 클래스에 접근하기 위해서는 내부 클래스 객체를 생성해야 함
이름이 있는 내부 클래스
내부 클래스에 이름이 있는 경우, 일반 클래스와 동일함
다른 클래스의 내부에 있다는 점과 main()에서 클래스를 생성하는 방식만 다름
외부 클래스의 멤버 변수 및 메소드에 편리하게 접근하기 위해 사용
main() 메소드에서 내부 클래스 객체 생성법
Outer클래스명.Inner클래스명 Inner객체명 = Outer객체명.new Inner클래스명()
// 외부 클래스 객체 생성
Outer out = new Outer();
// 내부 클래스 객체 생성
Outer.Inner in = out.new Inner();
사용례
package j200204;
public class Outer {
// 멤버 변수
int a;
// 생성자
public Outer() {
// 멤버 변수 초기화
a = 10;
}
public void aa() {
System.out.println("aa 메소드 호출");
// 메소드 내부에서 내부 클래스 객체 생성 및 메소드 호출
Inner in = new Inner();
in.cc();
}
public void bb() {
System.out.println("bb 메소드 호출");
}
// ========= Inner Class =========
public class Inner {
// 내부 클래스 멤버 변수
int ax;
// 내부 클래스 생성자
public Inner() {
ax = 15;
}
// 내부 클래스 메소드
public void cc() {
System.out.println("내부 클래스 cc 메소드 호출");
System.out.println("외부 a: " + a + ", 내부 ax: " + ax);
bb();
}
}
public static void main(String[] args) {
// Outer 클래스 객체 생성
Outer out = new Outer();
// main()에서 Inner 클래스 생성
Outer.Inner oi = out.new Inner();
System.out.println("==내부 클래스 멤버 변수==");
// 내부 클래스 객체 oi의 멤버 변수 ax출력
System.out.println("ax: " + oi.ax);
System.out.println("====메소드 호출====");
// 외부 클래스 메소드 호출
// 메소드 호출 순서 out.aa -> in.cc -> out.bb
out.aa();
/*
==내부 클래스 멤버 변수==
ax: 15
====메소드 호출====
aa 메소드 호출
내부 클래스 cc 메소드 호출
외부 a: 10, 내부 ax: 15
bb 메소드 호출
*/
}
}
Anonymous inner class 익명 내부 클래스
클래스의 이름이 없는 경우로
상속받은 추상클래스 또는 인터페이스를 바로 객체로 생성해서 반환함
- 단 하나의 추상 클래스 또는 단 하나의 인터페이스를 바로 생성할 수 있음
- 클래스 마지막에 세미콜론(;)을 사용해서 익명 내부 클래스가 끝났다는 것을 표현
- 인터페이스나 추상 클래스 자료형으로 변수를 선언한 후
익명 내부 클래스를 생성해 변수에 대입할 수 있음 - 메소드 내부에 작성해서 메소드 반환형을 해당 인터페이스/추상클래스로 지정할 수도 있음
- 인터페이스와 추상 클래스 내부의 모든 추상 메소드를 반드시 오버라이딩 해야 함
형식
new 부모 추상클래스명(){
// 부모 추상클래스 추상 메소드 오버라이딩
};
new 부모 인터페이스명(){
// 부모 인터페이스 메소드 오버라이딩
};
사용례
OuterInter.java
OuterInter 인터페이스가 선언된 파일
package j200204;
public interface OuterInter {
public void interPrint();
}
OuterInner.java
추상 클래스 Abs를 선언하고
외부 클래스 OuterInner 내부에 추상 클래스 및 인터페이스 객체 생성
package j200204;
// 추상 클래스 선언
abstract class Abs {
// 추상 메소드
abstract public void absPrint();
// 일반 메소드
public void print() {
System.out.println("추상 클래스 일반 메소드 호출");
}
}
// 외부 클래스
public class OuterInner {
// 추상 클래스 상속 내부 익명 클래스 객체 생성
// 추상 클래스를 상속했기 때문에 자료형은 추상 클래스를 따름
Abs abs = new Abs() {
public void absPrint() {
System.out.println("추상 클래스 상속 내부 익명 클래스");
}
};
// 인터페이스 구현 내부 익명 클래스 객체 생성
// 인터페이스를 구현했기 때문에 자료형은 인터페이스를 따름
OuterInter oi = new OuterInter() {
public void interPrint() {
System.out.println("인터페이스 구현 내부 익명 클래스 ");
}
};
public static void main(String[] args) {
// 외부 클래스 객체 생성
OuterInner outin = new OuterInner();
// 외부 클래스 객체에서 인터페이스 객체의 재정의된 interPrint() 메소드 호출
outin.oi.interPrint();
// 추상 클래스 객체의 재정의된 absPrint() 메소드 호출
outin.abs.absPrint();
// 추상 클래스 객체의 일반 메소드 역시 호출 가능
outin.abs.print();
/*
인터페이스 구현 내부 익명 클래스
추상 클래스 상속 내부 익명 클래스
추상 클래스 일반 메소드 호출
*/
}
}
클래스 내부에 또 다른 클래스를 작성하는 내부 클래스와
내부 클래스에 이름이 없는 경우인 익명 내부 클래스에 대해 알아보았습니다.
이름이 있는 내부 클래스의 경우 외부 클래스의 멤버 변수 및 메소드에 보다 편리하게 접근하기 위해 많이 사용되고,
익명 내부 클래스의 경우 이전에 GUI 구현시 많이 사용되었다고 합니다.