본문 바로가기

BACK

[기본 자료구조 - Class] 중첩 클래스

728x90

중첩 클래스

  • 멤버 클래스 (Member Class) - 인스턴스 내부 클래스, 정적 내부 클래스
  • 지역 클래스 (Local Class) - 지역 내부 클래스
  • 익명 클래스 (Anonymous Class) - 익명 내부 클래스

1. 멤버 클래스 : 선언이 다른 클래스 또는 인터페이스 선언에 의해 직접 둘러싸인 클래스

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으로 선언된 내부 클래스

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);
    }

 

2. 지역 클래스 : 이름이 주어진 중첩 클래스인 내부 클래스, 어떤 클래스의 멤버도 될 수 없다

1) 지역 내부 클래스 : 메소드 안에서도 클래스를 지역변수 처럼 선언해서 사용할 수 있다.

 

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

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();
    }

 

3. 익명 클래스  : 이름이 없는 클래스, 바깥 클래스의 멤버가 아님, 쓰이는 시점에 선언+인스턴스 생성

1) 익명 내부 클래스 : 익명 클래스는 추상 클래스를 상속받는 클래스를 굳이 만들어낼 필요가 없는 경우 사용한다.
                                   추상 클래스를 상속받는 클래스가 해당 클래스 안에서만 사용되고

                                   다른 클래스에서는 전혀 사용할 필요가 없을 때 사용한다.

 

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

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();
    }
}

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

728x90