(0) 내부 클래스의 종류

  • 인스턴스 내부 클래스
  • 정적(static) 내부 클래스
  • 지역(local) 내부 클래스
  • 익명(anonymous) 내부 클래스

(1) 인스턴스 내부 클래스

클래스 안에 선언된 클래스, 즉 필드를 선언하는 위치에 있는 클래스로,
중첩 클래스 또는 인스턴스 클래스라고 부르기도 한다.

package ex2_1;

public class InnerExam1 {
    class Cal{ 		//내부 클래스
        int value = 0;
        public void plus(){
            value++;
        }
    }

내부 클래스 안에 있는 함수를 쓰기 위해서는 아래 코드와 같이
외부 클래스를 먼저 생성하고, 이후 내부 클래스에서 함수를 호출해야 한다.

    public static void main(String[] args) {
        InnerExam1 t = new InnerExam1();
        InnerExam1.Cal cal= t.new Cal();
        cal.plus();
        System.out.println(cal.value);
    }

(2) 정적(static) 내부 클래스

필드가 static으로 선언된 내부 클래스.
정적 중첩 클래스 또는 스태틱 클래스라고도 부른다.

아래는 (1)에서 사용한 예시와 동일한 코드이다. 단지 static 으로 선언되었다.

	public class InnerExam2 {
   		static class Cal{
        	int value = 0;
        	public void plus(){
            	value++;
        }

정적 내부 클래스를 사용하는 방법은 아래와 같다.
반드시 외부 클래스를 먼저 선언하지 않아도 되고,
외부클래스.정적클래스명 으로 사용할 수 있다.

    public static void main(String[] args) {
        InnerExam2.Cal cal = new InnerExam2.Cal();
        cal.plus();
        System.out.println(cal.value);
    }

(3) 지역(local) 내부 클래스

메소드 안에서도 클래스를 지역변수 처럼 선언해서 사용할 수 있다.
이런 클래스를 지역 중첩 클래스 또는 지역 클래스라고 부른다.

public class InnerExam3 {
    public void exec(){ 	//메소드
        class Cal{ 			//지역 내부 클래스
            int value = 0;
            public void plus(){
                value++;
            }
        }
        /* 메소드 안에서만 Cal 객체 생성 및 메소드 호출 */
        Cal cal = new Cal(); 
        cal.plus();			
        System.out.println(cal.value);
    }
}

지역 내부 선언된 클래스는 메소드 안에서만 객체 생성 및 메소드 호출이 가능하다.

    public static void main(String[] args) {
        InnerExam3 t = new InnerExam3();
        t.exec();
    }

메인 메소드 안에서 사용시에는 외부 클래스 객체를 생성하고
이후 지역 클래스가 있는 메소드를 호출하여 동작시킬 수 있다.

(4) 익명(anonymous) 내부 클래스

또는 익명 중첩 클래스라고도 부른다.

익명 클래스는 추상 클래스를 상속받는 클래스를 굳이 만들어낼 필요가 없는 경우 사용한다.
추상 클래스를 상속받는 클래스가 해당 클래스 안에서만 사용되고
다른 클래스에서는 전혀 사용할 필요가 없을 때 사용한다.

예를 들어서, 아래와 같은 추상 클래스를 사용하기 위해서는
반드시 추상 클래스를 상속받은 자식 클래스가 해당 메소드를 구현해야만 한다.

public abstract class Action {
    public abstract void exec();
}

#1. 이렇게 자식 클래스를 만들어 오버라이드하고

public class MyAction extends Action {

    @Override
    public void exec() {
        System.out.println("exec");
    }
}

#2. 메인 메소드에서 추상 클래스인 부모를 대신해 자식 객체로 생성하는 것이다.

public class ActionExam {
    public static void main(String[] args) {
        Action action = new MyAction();
        action.exec();
    }
}

하지만 액션을 상속받은 익명클래스를 만들어서 사용하면
굳이 위처럼 번거롭게 자식 클래스를 별도로 생성하지 않아도 된다.

아래 코드처럼 추상 클래스 그대로 선언하고,
{}; 안에서 메소드를 오버라이딩 하는 것이다.


public class ActionExam {
    public static void main(String[] args) {
        Action action = new Action() {
            
            @Override
            public void exec() {
                System.out.println("exec");
            }
        };
        action.exec();
    }
}

그러면 이후 메인 메소드 안에서 메소드를 사용하면 된다.

Reference 🙏

0개의 댓글