일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- abstract
- array
- ArrayList
- Class
- collection
- database
- db
- DDL
- default
- DML
- Exception
- Generic
- HashSet
- Interface
- Java
- Java 입문
- java 자료형
- java 클래스
- JavaBean
- javabeans
- JAVA의 특징
- LinkedList
- linkedset
- list
- mariadb
- Private
- protected
- public
- RuntimeException
- set
- Today
- Total
GeehDev
[Java] 이너 클래스 본문
이너 클래스
이너클래스란, 클래스 내부에 포함되는 이너 클래스를 말하며, 아래 3가지로 구분됩니다.
- 인스턴스 이너클래스
- 정적(static) 이너클래스
- 지역 이너클래스
인스턴스 이너 클래스
객체 내부의 인스턴스 멤버로 존재하는 이너 클래스 입니다.
- 자신의 아우터 클래스의 모든 멤버에 마치 자기 것인냥 접근할 수 있습니다. (모든 접근지정자)
- 컴파일 수행 시 각 클래스별로 바이트 코드로 생성되며 이 때
아우터$이너클래스.class
파일로 생성됩니다.
객체 생성하기
//사용법
아우터클래스 변수명 = new 아우터클래스();
아우터클래스.이너클래스 변수명 = 아우터변수명.new 이너클래스();
//사용예시
class A {
class B {}
}
//-----------------
A a = new A();
A.B b = a.new B();
//이너클래스의 자료형은 아우터.이너클래스명
//아우터 클래스의 참조변수를 이용해 생성해야하기 때문에 a.new B()로 작성합니다.
- 아우터 클래스의 객체를 생성합니다. =>
A a = new A();
- 아우터 객체의 참조변수 이용해 이너 클래스의 객체를 생성합니다. =>
A.B b = a.new B();
이 때 이너클래스의 자료형은아웃터클래스.이너클래스
입니다. 이는 해당 이너클래스가 바이트코드로 생성될 때아우터$이너클래스.class
생성되기 때문입니다.
이너 클래스 내에서 this
이너클래스와 아우터클래스 에서 필드명 또는 메서드명이 중복될 경우 우선적으로 해당 이너클래스 내에 필드, 메서드를 가져옵니다.
이 때 아우터의 필드, 메서드를 가져와야할 경우 this
키워드를 사용할 수 있습니다. 다만, 이너클래스도 클래스이기 때문에 this
를 사용하면 해당 이너클래스 본인 자신을 가르키기 때문에 아우터클래스명.this
로 사용해야합니다.
class A {
int a = 4;
int b = 3;
class B {
int a = 5;
void abc() {
System.out.println(a); //이너클래스 내 a 호출 = 5
System.out.println(this.a); //이너클래스 내 a 호출 = 5
System.out.println(A.this.a); //아우터클래스 내 a 호출 = 4
System.out.println(b); //아우터클래스 내 b 호출
}
}
}
정적 이너 클래스
이너 클래스 앞에 static
제어자가가 포함된 이너 클래스 입니다.
- 자신의 아우터 클래스의 멤버 중 정적(statci)멤법에만 접근할 수 있습니다.
- 컴파일 수행 시 각 클래스별로 바이트 코드로 생성되며 이 때
아우터$이너클래스.class
파일로 생성됩니다. - 정적멤버이기 때문에 아우터 클래스 참조 변수 없이 접근할 수 있습니다.
객체 생성하기
//사용법
아우터클래스.이너클래스 변수명 = new 아우터클래스.이너클래스();
//사용예시
class A {
class B {}
}
//-----------------
A.B b = new A.B();
//이너클래스의 자료형은 아우터.이너클래스명
지역 이너 클래스
클래스의 멤버가 아닌 메서드 내에 정의되는 지역 이너 클래스 입니다.
- 자신의 아우터 클래스의 모든 멤버에 마치 자기 것인냥 접근할 수 있습니다. (모든 접근지정자)
- 추가로 자신이 정의된 메서드 내 지역변수도 사용할 수 있으나,
이 때 접근하는 모든 지역변수는final
상태여야합니다. (final
아닌 지역변수 접근 시 컴파일러가 강제로final
상태 추가) - 해당 지역 이너 클래스가 정의된 메서드 내에서만 객체를 생성할 수 있습니다.
- 컴파일 수행 시 각 클래스별로 바이트 코드로 생성되며 이 때
아우터$+숫자+이너클래스.class
파일로 생성됩니다. (숫자는 동일한 지역이너클래스 명이 있을 때 +1)
객체 생성하기
//사용법
이너클래스명 변수 = new 이너클래스명();
//사용예시
class A {
void abc() {
class B {}
B b = new B(); //해당 메서드 내에서만 객체 생성 가능
}
}
//-----------------
A.B b = new A.B();
//이너클래스의 자료형은 아우터.이너클래스명
익명 이너 클래스
익명 이너 클래스는, '이름을 알 수 없는 이너 클래스'를 말합니다.
//사용법
클래스명 참조변수명 = new 생성자() {
접근제어자 리턴타입 메서드명() {
...;
}
}
//사용예시
interface A {
public abstract void abc();
}
class B {
A a = new A() {
//A인터페이스를 상속받아 추상메서드 abc()를 구현하는 익명 이너 클래스
public void abc() {
...;
}
}
void def() {
a.abc();
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.def(); //b.def() 내에 a.abc() 메서드가 포함되어 있음.
}
}
익명 이너 클래스의 특징
1. 정적 익명 이너 클래스 존재 불가
: 인스턴스 익명 이너 클래스, 지역 익명 이너 클래스가 있으며, 정적(static) 익명 이너클래스는 존재할 수 없다.
정적(static)의 경우 객체 생성없이 사용 가능해야하는데, 익명 이너클래스의 경우 이름이 없기 때문에 객체 생성 불가
interface A {
public abstract void abc();
}
class B {
A a = new A() { // 인스턴스 익명 이너 클래스
public void abc() {
...;
}
}
void def() {
A aa = new A() { // 지역 익명 이너 클래스
public void abc() {
...;
}
}
}
}
2. 익명 이너 클래스 내 추가 메서드 작성은 가능 / 해당 이너 클래스 밖에서 사용 불가
: 익명 이너 클래스에서도 부모클래스(인터페이스)에서 오버라이딩한 메서드 외 추가 정의 메서드를 작성할 수는 있으나, 익명 이너 클래스의 경우 클래스명이 없어 늘 부모 타입으로만 객체 생성이 가능하여, 추가 작성한 메서드는 익명 이너클래스 내부에서만 사용 가능하다.
interface A {
public abstract void abc();
}
class B {
A a = new A() {
public void abc() { // 부모 인터페이스의 추상메서드 오버라이딩
def(); // 추가 정의 메서드를 내부적으로 호출 가능
}
public void def() { //추가 정의 메서드
...;
}
}
a.abc(); //사용가능
a.def(); //부모 클래스(인터페이스)에 없는 메서드 익명 이너클래스 밖에서 사용불가
}
인터페이스 타입의 매개변수에 익명 이너클래스 활용
인터페이스 타입의 매개 변수란,
interface A {
public abstract void abc();
}
class B {
void def(A a) { //인터페이스 A 타입을 매개변수로 받는 메서드
a.abc();
}
}
위와 같은 형태로 매개변수로 받는 A 인터페이스를 구현한 자식 클래스의 객체가 매개변수로 전달이 필요한 메서드를 말합니다.
이 매개변수를 전달하는 방법으로는 4가지 형태가 있습니다.
- 방법 ① : A 인터페이스를 구현한 구현 클래스 작성 후 각 각 객체 생성하여 전달
class C implements A {
public void abc() {
...;
}
}
B b1 = new B();
A ac = new C(); //B.def()의 매개 변수가 A타입으로 정의되어있기 때문에 A타입으로 C객체 생성 필요
bb.def(ac);
- 방법 ② : A 인터페이스를 구현한 구현 클래스 작성 후 new 생성자 이용
class C implements A {
public void abc() {
...;
}
}
B b2 = new B();
b2.def(new C());
- 방법 ③ : A 인터페이스를 구현한 익명 이너클래스 작성하여 객체 생성 후 전달
B b3 = new B();
A a1 = new A() {
public void abc() {
...;
}
}
b3.def(a1);
- 방법 ④ : 매개변수로 바로 익명 이너 클래스 작성하여 전달
B b4 = new B();
b4.def(new A() {
public void abc() {
...;
}
});
방법 ④의 경우 이벤트 처리 시 많이 이용된다고 합니다.
이너 인터페이스
인터페이스를 클래스 내부에 정의하는 것을 말합니다. 해당 클래스 내에서 의존적인 기능을 수행할 때 사용할 수 있습니다. (주로 이벤트 처리 시 이용 = '리스너')
class A {
static interface B {
public abstract abc();
}
}
이너 인터페이스의 특징
1. 정적 이너 인터페이스만 존재할 수 있습니다.
모든 이너 인터페이스는 정적(static) 인터페이스만 존재할 수 있으며, static
제어자 미입력시 컴파일러가 자동으로 추가해줍니다.
2. 이너 인터페이스도 자체적으로 객체를 생성할 수 있습니다.
이너 인터페이스도 인터페이스이기 때문에 자체적으로 객체를 생성할 수 없으며, 구현 클래스를 작성 후 구현 클래스의 생성자로 객체 생성 또는 익명 이너 클래스를 활용하여 객체를 생성해줄 수 있습니다.
3. 이너 인터페이스의 객체 타입은 아웃터클래스명.이너인터페이스명
입니다.
이너 인터페이스의 경우 아웃터 클래스 내부에 위치해 있기 때문에 이너클래스와 유사하게 타입이 아웃터클래스명.이너인터페이스명
이 됩니다.
class A {
static interface B {
public abstract abc();
}
}
//구현 클래스 작성
class C implements A.B {
//abc 메서드 구현
}
C c = new C();
c.abc();
//익명 이너 클래스 작성
A.B ab = new A.B() {
//abc 메서드 구현
}
ab.abc();
참고
Do it! 진짜 개발자가 되는 Java 프로그램 입분서 자바 완전 정복 - 김동형
위 책을 공부하며 작성하고 있습니다!
'Study > Java' 카테고리의 다른 글
[Java] 제네릭 (2) | 2024.09.15 |
---|---|
[Java] 예외 처리 (1) | 2024.09.15 |
[Java] 추상 클래스와 인터페이스 (1) | 2024.09.15 |
[Java] 자바 제어자 - 접근 제어자/static/일반 제어자 (0) | 2024.09.15 |
[Java] 클래스의 상속과 다형성 (0) | 2024.09.15 |