2023_1_14_TIL
인스턴스 멤버 이너 클래스
- 객체 내부에 멤버 형태로 존재
- outer class의 모든 접근 지정자 멤버에 접근 가능
- 순서 -> 아우터 클래스 -> 이너 클래스
- 이너 클래스는 독립적 사용 불가능
- 인스턴스 이너 클래스 객체 생성
- 아우터 클래스 객체 생성 -> 이너 클래스 객체 생성
- 아우터 클래스 객체를 참조하기 위해서(반드시 참조해서 생성해야 함)
- 이너 클래스 객체의 자료형 A.B 임 (B 아님)
class A {
public int a = 3;
protected int b = 4;
int c = 5;
private int d = 6;
void abc() {
System.out.println("A 클래스 메소드 abc()");
}
class B {
void bcd() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
abc();
}
}
}
public class CreateObjectAndAccessMember {
public static void main(String[] args) {
A a = new A();
A.B b = a.new B();
b.bcd();
}
}
- 아우터 클래스의 객체 참조
- 아우터클래스.this.아우터클래스멤버 -> 여기서 this는 아우터 클래스를 의미
- 반면에 this.~~ -> 이너클래스쪽 참조 this임
class A {
int a = 3;
int b = 4;
void abc() {
System.out.println("A 클래스 메소드");
}
class B {
int a = 3;
int b = 4;
void abc() {
System.out.println("B 클래스 메소드");
}
void bcd() {
System.out.println(a);
System.out.println(b);
abc();
System.out.println(A.this.a);
System.out.println(A.this.b);
A.this.abc();
}
}
}
public class UseMembersOfOuterClass {
public static void main(String[] args) {
A a = new A();
A.B b = a.new B();
b.bcd();
}
}
정적 멤버 이너 클래스
- 아우터 클래스의 객체 생성 없이 객체 생성 가능 -> 아우터 클래스 중 정적 멤버만 사용가능
- 정적 클래스 객체 생성하기
class A {
int a = 3;
static int b = 4;
void method1() {
System.out.println("instance method");
}
static void method2() {
System.out.println("static method");
}
static class B {
void bcd() {
System.out.println(b);
method2();
}
}
}
public class CreateObjectAndAccessMember {
public static void main(String[] args) {
A.B b = new A.B();
}
}
지역 이너 클래스
- 메서드 안에서 정의됨
- 메서드가 호출될 때만 메모리에 로딩
- 형태 -> 아우터클래스& + 숫자 + 지역ㅇ너클래스.class -> 숫자있는 이유는 메소드가 여러개 있으면 구분 할려고 ㅇㅇ
- 지역 이너 클래스 객체 생성
- 아우터클래스 멤버 접근 지정자와 상관없이 사용 가능
- 자신이 정의된 메소드 내의 지역변수도 클래스 내부에서 사용 가능
- 해당 지역변수는 final로 선언되어야 함(약속
)
- 해당 메소드 안에서만 객체 생성이 가능 -> 일반 클래스의 객체 생성과 동일
class A {
int a = 3;
void abc() {
final int b = 5;
class B {
void bcd() {
System.out.println(a);
System.out.println(b);
a = 5;
}
}
B bb = new B();
bb.bcd();
}
}
public class AccessMemberAndLocalVariable {
public static void main(String[] args) {
A a = new A();
a.abc();
}
}
익명 이너 클래스의 정의와 특징
- 위치에 따라 분류하는 익명 이너 클래스
- 인스턴스 익명 이너 클래스 -> 클래스의 중괄호 바로 아래에 사용
- 지역 익명 이너 클래스 -> 메서드 내부에서 사용
- 인터페이스를 상속한 이너 클래스를 생성해 인터페이스 객체 생성
class A {
C c = new B();
void abc() {
c.bcd();
}
class B implements C {
public void bcd() {
System.out.println("인스턴스 이너 클래스");
}
}
}
interface C {
public abstract void bcd();
}
public class AnonymousClass_1 {
public static void main(String[] args) {
A a = new A();
a.abc();
}
}
- 익명 이너 클래스를 활용해 인터페이스 객체 생성
- 익명 이너 클래스 사용시 -> 항상 부모 타입으로만 선언
- 오버라이딩 메소드 내부에서 호출 가능 -> 작성 내용 많다? -> 메소드 분리 후 작성
class A {
C c = new C() {
public void abc() {
System.out.println("익명 이너 클래스");
}
};
void bcd() {
c.abc();
}
}
interface C {
public abstract void abc();
}
public class AnonymousClass_2 {
public static void main(String[] args) {
A a = new A();
a.bcd();
}
}
익명 이너 클래스를 활용한 인터페이스 타입의 입력 매개 변수 전달
- 인터페이스 객채를 생성하고, 메소드의 입력 매개변수로 전달하는 방법 4가지
- B() 생성자를 이용해, 객체 A 타입의 참조변수에 저장 -> 매개변수로 넘기기
- 귀찮게 객체의 참좃값만을 전달할 목적? -> 입력매개변수 위치에 new키워드로 객체 생성 -> 객체의 참좃값 메소드로 전달
- 익명 이너 클래스를 사용해서 객체 생성 -> 객체 참조하는 변수를 입력매개변수로 전달
- 메소드 입력매개변수자리에 곧바로 익명 이너클래스 객체 생성 후 전달
- 클래스 정의 및 참조 변수명을 사용/미사용했을 때 입력매개변수 객체 전달
interface A {
public abstract void abc();
}
class B implements A {
public void abc() {
System.out.println("입렵매개변수 전달");
}
}
class C {
void cde(A a) {
a.abc();
}
}
public class AnonymousClass_3 {
public static void main(String[] args) {
C c = new C();
A a = new B();
a.abc();
c.cde(new B());
}
}
- 클래스 미정의 및 참조 변수명을 사용/미사용했을 때 입력개매변수 전달
interface A {
public abstract void abc();
}
class C {
void cde(A a) {
a.abc();
}
}
public class AnonymousClass_4 {
public static void main(String[] args) {
C c = new C();
A a = new A() {
public void abc() {
System.out.println("입력매개변수 전달");
}
};
c.cde(a);
c.cde(new A() {
public void abc() {
System.out.println("입렵매개변수 전달");
}
});
}
}
- 익명 이너 클래스 사용하면 직접 클래스 생성 X -> 하지만 여러 객체 생성? -> 직접 클래스 잡자
이너 인터페이스의 정의와 특징
- 이벤트 처리에 많이 사용
- 정적 이너 인터페이스만 존재
- 아우터클래스명$이너인터페이스명.class 형태
- 일반적인 인터페이스 생성 방식과 같음
- 차이점 -> 클래스 내부에 인터페이스 존재 -> 클래스명.인터페이스명(객체 타입)
class A {
static interface B {
public abstract void bcd();
}
}
class C implements A.B {
public void bcd() {
System.out.println("이너 인터페이스 구현 클래스 생성");
}
}
public class CreateObjectOnInnerInterface {
public static void main(String[] args) {
A.B ab = new C();
C c = new C();
c.bcd();
A.B b = new A.B() {
public void bcd() {
System.out.println("익명 이너 클래스로 객체 생성");
}
};
b.bcd();
}
}
이벤트 처리기능 작성
class Button {
OnClickListener ocl;
void setOnClickListener(OnClickListener ocl) {
this.ocl = ocl;
}
interface OnClickListener {
public abstract void onClick();
}
void onClick() {
ocl.onClick();
}
}
public class ButtonAPIExample {
public static void main(String[] args) {
Button btn1 = new Button();
btn1.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick() {
System.out.println("개발자 1: 음악 재생");
}
});
btn1.onClick();
Button btn2 = new Button();
btn2.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick() {
System.out.println("개발자 2: 네이버 접속");
}
});
}
}