Java Syntax - (13) 이너 클래스 & 이너인터페이스 | 근데 이제 익명을 곁들인...

가빈·2023년 12월 18일
post-thumbnail

이너클래스

: 클래스 내부에 포함된 클래스

멤버 클래스

1. 인스턴스 멤버 이너클래스

: 객체 내에 있는 일반 이너클래스

특징

  • 객체를 만들어야 사용가능
  • 외부 클래스의 모든 접근지정자 멤버 접근이 가능
    ❗️일반 클래스의 객체 생성 후 그 안에 이너클래스를 만들고 그 이너클래스 내에 또 객체를 생성해야한다

내부클래스에서 객체만들기

  • 클래스명 : 외부클래스$내부클래스.class
  • 생성방법 : 외부클래스 객체 생성 후 내부클래스 객체생성
외부클래스 a = new 외부클래스();
외부클래스.내부클래스 b = 외부클래스 객체.new 내부클래스();

A a = new A();
A.B b = a.new B();//이너클래스 객체생성

외부클래스의 객체 참조

  • 객체참조명 : 외부클래스명.this.__
class A {
	int a=3;
    int b=4;
  class B {
      int a=5;
      int b=6;

      void bcd() {
          System.out.println(A.this.a);//3
          System.out.pritnln(this.a);5
      }
  }
}

2. 정적(static)멤버 이너클래스

: 객체생성없이 사용하는 이너클래스

특징

  • static 멤버들만 접근가능(일반클래스는 객체를 생성해야하기 때문)
  • 객체생성 안 하고 static 영역 메모리에 바로 사용가능

내부클래스에서 생성자로 직접 객체생성

  • 클래스명 : 외부클래스$이너클래스.class

지역클래스 : 메서드 내에 있는 이너클래스

특징

  • 외부클래스의 필드는 모두 접근가능
  • ⭐️메서드 지역변수는 final만 사용해야한다(쓰지 않으면 컴파일러 자동생성) -> 지역변수는 사용하면 메모리에서 삭제되는데 그걸 지역클래스에서 사용하게 되면 의미없는 클래스가 된다 이를 방지하기 위해서 final로 자동 정의되고 final 영역에 남게 되기 때문이다


익명이너클래스

: 이름을 알 수 없는 이너클래스

상속파트에 쓰임새가 나오므로 이해가 안 가면 상속편에서 익명이너클래스를 보고오자!!!
좀 이해가 안가는 부분이 생긴다

  • 이름이 없어서 한번에 객체를 2개 이상 생성이 불가능

원래대로라면,,,,

interface C {
	public abstract void bcd();
// 자식클래스로 객체생성방법과 익명이너클래스로 객체생성이가능하다
}


class A {
	C b = new B();//b에 c의 내용이 상속되어서 B()로 객체생성
	void abc() {
    	b.bcd();
    }
class B implements C { //객체 생성을 위해 이너클래스 만듦
	public void bcd() { //인터페이스 c를 구현함
    	System.out.pritnln(...);

    void cde(){
    	}
    }

}

}
B b = new B();
b.bcd();//가능
b.cde();//가능 -> 메서드 2개 호출 가능

-> 스스로 클래스를 생성해서 구현하고 그 이너클래스로 객체생성했어야 하는건데 익명클래스를 이용해서 클래스 만드는 일을 컴파일러에게 넘길 수 있다.\

class A {
	C b = new C(){
    	public voic bcd() {
		//구현해야하는 부분을 객체 생성 중괄호 부분에 적는다
        	System.out.println(...);
			cde();//내부 호출은 가능
        }
		void cde() {
        ... //정의는 가능
        }
    };
	
}
c.bcd();//가능
c.cde();//c객체만 가리키기 때문에 익명의 객체 내에 있는 cde 클래스 이름을 알지 못해서 호출 불가

-> 이렇게 만들어서 이름을 모르는 익명이너클래스를 컴파일러가 만들어준다 하지만 여러 메서드 호출은 못한다

익명이너클래스를 이용한 인터페이스 타입 매개변수 전달

인터페이스 타입으로 매개변수를 받게 되면 문제는 추상메서드인데 객체를 생성해야하는 문제점이 생기게 된다

class C {
	void cde(A a) {//인터페이스 A타입을 매개변수로 함 -> 객체가 생성되어야 하는데?????
	a.abc();//구현한 메서드 불러오기
	}
}
interface A {
	public abstract void abc();
}
class B implements A {
	public void abc() {//추상메서드 구현
    ...
    }
}

1. 클래스명O + 참조변수명O

C c = new C();//위에서와 마찬가지로 인터페이스랑 객체생성불가하다
A a1 = new B;//자식클래스 B클래스로 A를 상속받아서 객체 생성한다
c.cde(a1);// a1은 B타입을 지정되고 B는 A 인터페이스를 포함하므로 성공!

2. 클래스명O + 참조변수명X

C c = new C();//위에서와 마찬가지로 인터페이스랑 객체생성불가하다
c.cde(new B());// 방법 1의 약식버전이다 a1이 중복되므로바로 new B를 넣는다

자식클래스를 사용하지 않는 방법으로 진행해보자.

3. 클래스명X + 참조변수명O(활용도good!)

C c = new C();
A a = new A() {//익명이너클래스를 이용한다
	public void abc() {
    ..//추상메서드 구현
    }
};
c.cde(a);

4. 클래스명X + 참조변수명X

c.cde(new A() { 
//3번의 약식표현으로 바로 생성자 내에 내용을 넣는다
	public void abc() {
    ...
    }
});


이너인터페이스

특징

  • 외부클래스와 밀접한 관계가 있을 때 사용(외부클래스의 내용물을 쓰려고)
  • UI 이벤트 처리로 가장 많이 사용(클릭, 터치)
  • static 을 생략한 경우, 자동으로 삽입 -> 정적이너인터페이스만 가능(객체생성없이 바로 사용) : 너무 당연한 얘기다 왜냐면 객체생성불가니까

이너인터페이스명 : 외부클래스$이너인터페이스.class (클래스 내에 있어서 .class 사용)

객체생성 + 사용

역시나 객체생성을 할 수 없기 때문에 따로 클래스를 만들어서 객체 생성해야한다

class A {
	....
	static interface B {
    	void bcd();
    }
}

방법1) 일반 클래스 생성해서 구현후 객체생성

class C implements A.B{
//A클래스의 B인터페이스 구현
	public void bcd() {
    	....
    }
}
C c = new C();//C객체 만듦
c.bcd();//구현된 메서드이므로 자기메서드처럼 호출가능

방법2) 익명이너클래스 사용

A.B a = new A.b() {
//익명 이너클래스를 사용해서 구현
	public void bcd() {
    ...
    }
}
a.bcd(); //중복되는 객체생성없이 바로 호출
profile
지금부터 시작!

0개의 댓글