본문 바로가기

PL(ProgrammingLanguage)/JAVA

내부클래스 - local 클래스 / 익명클래스

세번째.

메소드 안에 클래스를 선언한 경우, 지역 중첩 클래스 또는 지역 클래스(local class)라고 한다.

 

지역중첩클래스 이름에서 느껴지듯이 이 내부 클래스가 인스턴스변수로 선언되는 것이 아니라

메소드안에서 선언되는 경우를 말한다.

 

package Java02;

import com.sun.org.apache.bcel.internal.classfile.InnerClass;

public class InnerExam2 {
   
    public void exec() {
        // 메소드를 정의하고 이 메소드안에 Cal이라는 클래스가 생성되어 있는 경우
        class Cal {
            // 클래스를 선언하는 거니깐 똑같이 필드를 선언할 수도 있고
            // 메소드를 정의해 놓을 수도 있다.
            int value = 0;

            public void plus() {
                value++;
            }
        }
    }
}

이랬을 때 이 Cal 이라는 객체를 생성해서 사용할 수 있는 부분은 메소드안에서만 사용할 수 있다.
메소드 안에서 Cal 이라는 객체를 생성할 수 있을 것이고, 메소드 안에서 Cal이라는 객체가 가진 메소드를 호출한다던가  

Cal 가지고 있는 value를 호출해서 사용할 수 있다.

 

public class InnerExam2 {
   
    public void exec() {
        // 메소드를 정의하고 이 메소드안에 Cal이라는 클래스가 생성되어 있는 경우
        class Cal {
 
            int value = 0;

            public void plus() {
                value++;
            }
        }
       
        Cal cal = new Cal();
        cal.plus();
        System.out.println(cal.value);
    }
}

 

-- 사용해보기

package Java02;

import com.sun.org.apache.bcel.internal.classfile.InnerClass;

public class InnerExam2 {
   
    public void exec() {

        class Cal {
          
            int value = 0;

            public void plus() {
                value++;
            }
        }
    
        cal.plus();
        System.out.println(cal.value);
    }

    public static void main(String[] args) {
        //이것을 사용하기 위해서는 InnerExam2 객체를 생성
        InnerExam2 t = new InnerExam2();
       
        t.exec();

    }
}

-- 실행결과

 

InnerExam2가 가지고 있는 메소드를 호출할 때, 내부적으로 Cal 이라는 클래스가 하나 생성이 되고 
Cal이라는 클래스가 정의되어 있는 부분이 수행되는 것을 알 수 있다.
이렇게 메소드 안에서도 클래스를 지역변수처럼 선언해서 사용할 수 있다.

 


네번째.

익명 중첩 클래스: 익명 클래스라고 보통 말하며, 내부 클래스이기도 하다.

 

 

 Action이라는 클래스가 추상메소드인 exec이라는 메소드를 가지고 있었을 때,
이런 추상클래스를 사용하기 위해서는 반드시 이 클래스를 상속받은 자식클래스가 해당메소드를 구현해야 한다.

 

 

Action.java

package Java02;

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

 

 

그러면 Action을 상속받고 있는 MyAction이라는 클래스를 작성해보자.

 

MyAction.java

package Java02;

// Action이라는 추상클래스를 상속받고 있는 MyAction 클래스
public class MyAction extends Action{
    // 그러면 반드시 추상클래스가 갖고있었던 메소드를 구현하도록 나올 것이다.
    @Override
    public void exec() {
        System.out.println("exec");
    }
    // 이게 구현하는 형태였다라고 기억.
}

 

1. 일반적인 형태


Action 타입의 Action을 하나 선언하고, 반드시 Action은 추상클래스기 때문에 객체 자체가 생성되지 않는다.
그래서 생성은 MyAction이라고 하는 자식클래스가 생성되어야 한다.
이때,  Action이 가지고 있는 메소드를 사용할 수 있게 된다.

 

package Java02;

public class ActionExam {
    public static void main(String[] args) {

      
        Action action = new MyAction();
        action.exec();

    }
}

 

 

2.  익명클래스 형태

 

그런데 익명클래스는 자식클래스인 MyAction을 만들지 않고,
이 ActionExam에서 Action을 상속 받은 익명클래스를 만들어서 사용하도록 쓸 수 있다.

 

Action action = new Action()는 추상클래스이기때문에 Action 자체가 생성 되지는 않는다.
 아래와 같이 익명으로 클래스가 하나 만들어지게 된다.

 

 Action action = new Action() {
           
           @Override
            public void exec() {

            }
        };

 

생성자 다음에 나오는 중괄호 열고 닫고 하면 이 부분이 나오는데

해당 생성자 이름에 해당하는 클래스를 상속받은 이름없는 객체를 만든다는 것을 의미한다.
(괄호안에는 메소드를 구현하거나 추가할 수 있다.)

 

이렇게 생성된 이름없는 객체를 Action이라고 하는 참조 변수가 참조하도록 하였다. 그리고 exec메소드를 호출했다.

 

익명 클래스를 만드는 이유는 Action을 상속받는 클래스를 굳이 만들어 낼 필요가 없는 경우에 사용할 수 있다.
Action을 상속 받는 클래스가 해당 클래스 내에서만 사용이 되고, 다른 클래스에서는 전혀 사용할 필요가 없는 경우가 있을 수 있다.
이랬을 때 사용할 수 있는 것이 익명클래스라고 한다.

 

-- 완성 코드

package Java02;

public class ActionExam {
    public static void main(String[] args) {

        Action action = new Action() {
            @Override
            public void exec() {
                // 똑같이 이 부분을 수행하는 메소드를 만들 수 있게된다.
                System.out.println("exec");

            }
        };
        // 이 때 사용하는 방법은  action.해당메소드 호출 
        // ->  앞서 사용한 경우랑 똑같이 해당메소드를 사용할 수 있게된다.
        action.exec();

    }
}

 

-- 전체코드

package Java02;

public class ActionExam {
    public static void main(String[] args) {

//        Action action = new MyAction();
//        action.exec();

        Action action = new Action() {
            @Override
            public void exec() {
          
                System.out.println("exec");

            }
        };
      
        action.exec();

    }
}

 

-- 실행결과

'PL(ProgrammingLanguage) > JAVA' 카테고리의 다른 글

throws  (0) 2021.10.16
Exception - 예외  (0) 2021.10.13
내부 클래스 - instance 클래스/ static 클래스  (0) 2021.10.12
인터페이스(interface)의 default method  (0) 2021.10.12
인터페이스(interface) 사용  (0) 2021.10.12