Java/java

java :) inner class란?

euncheol kim 2022. 4. 22. 18:40

 

 

goal

java 내부 클래스(inner class)에 대해서 이해한다.


 

1 ] 내부클래스 (inner class)

class Outside {
    // ...
    class Inner {
    //...
    }
}

1. 개념

내부클래스는 클래스 내에 선언된 클래스이다.

 

2. 사용목적

밖의 클래스와 내부 클래스가 긴밀한 관계에 있기 때문에

 

3. 장점

  • 내부클래스에서, 외부 클래스의 멤버(필드)들을 쉽게 접근할 수 있다.
  • 코드의 복잡성을 줄일 수 있다.
  • 외부에서 불필요한 클래스를 은닉함으로써 코드의 복잡성을 줄일 수 있다. (캡슐화)

 

4. inner class의 종류

  1. 정적 클래스 (static class)
  2. 인스턴스 클래스 (instance class)
  3. 지역 클래스 (local class)
  4. 익명 클래스 (anonymous class)

[1] static class

- 외부 클래스의 field 선언부에 위치하고 static 키워드가 붙은 내부 클래스.

  • static이 붙어있기 때문에 외부 클래스의 객체를 생성하지 않고도 내부 클래스의 객체를 생성할 수 있다.
  • 내부에는 instance member와, static member 모두 선언 할 수 있다.
class Outside {
    satic class StaticInner {
        int data;
        static int data2;
    }
}
 Outside.StaticInner staticInner = new Outside.StaticInner();

※ class에 붙는 static과 멤버에 붙는 static의 의미 차이

우선 둘의 의미는 다름을 인지하자. 각각의 의미는 아래와 같다.

  • 멤버에 붙는 static : 정적 메모리를 잡아준다는 의미로, 컴파일 타임에 컴파일러가 메모리 할당하기 때문에 객체 생성없이도 사용 가능하다.
  • class에 붙는 static : 외부 클래스의 객체 생성없이 내부 클래스의 객체를 생성할 수 있다는 의미

 

[2] instance class

- 외부 클래스의 field 선언부에 위치하고 static 키워드가 없는 내부 클래스

  • 외부 클래스의 멤버이기 때문에 외부 클래스의 객체 먼저 생성한 후 내부 클래스의 객체를 생성하여 사용해야한다.
  • instance class 내부에는 instance member만 선언가능하다 ∴ static member는 선언 불가하다.
  • 주로 외부 클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언한다.
class Outside {
    class InstanceInner {
        int data;
    }
}
 /*

     inner class에서 instance class의 객체를 생성하기 위해서는
     외부클래스 객체 생성이 먼저 이루어져야한다.
 */

 Outside outside = new Outside(); // 외부클래스 객체생성
 Outside.InstanceInner instanceInner = new Outside.InstanceInner(); // 내부클래스 객체생성

 

[3] local class

- 외부 클래스의 메소드 내부에 위치하는 클래스 (지역변수와 같은 성질을 지닌다.)

  • 접근 제한자와 static을 붙일 수 없다. 메소드 내부에서만 사용되므로 접근을 제한할 필요가 없고,
    애초에 메소드 내에는 static 멤버를 선언할 수 없기 때문이다.
class Outside {
    static void method1() {
        class LocalInner {
            int data;
        }

        LocalInner localInner = new LocalInner();
        localInner.data = 10;
    }
}

 

[4] anonymous class

참고 블로그 : 익명클래스 사용방법, https://yookeun.github.io/java/2017/01/24/java-anonymousclass/, 와이케이의 마구잡이

- anonymous class는 클래스를 정의하는 동시에 객체를 생성할때 만들어지는 클래스이다.

  • 이름이 없는 클래스이다.
  • Interface, Class 모두 익명 클래스로 객체를 만들 수 있다.
  • 한 번만 객체를 만들 때 사용한다. (일회용 클래스) 즉, 프로그램에서 일지적으로 한번만 사용되고 버려지는 객체, 이 말은 다른 뜻으로 재사용이 되지 않는다는 것과 같다.
  • 사용하는 이유는 아래와 같다.
    • 한 번만 사용되고 버려질 클래스를 대체하여 사용
      ∴ class파일을 만드는 것을 억제하여 저장공간의 이점을 가진다.
// 익명클래스 만드는 형식
 부모클래스 인스턴스 = new 부모클래스() {

 };
public class Person {
     void  whoAmI() {
        System.out.println("나는 Person 이다.");
    }
}
public static void main(String[] args) {
        Person p = new Person() {
            String name = "Kim";
            @Override // 재정의
            void whoAmI() {
                System.out.println("나는 " + name + " 이다.");
            }
        };
        p.whoAmI();  // 나는 Kim 이다. 
    }

※ 익명클래스 사용의 주의점

  • 익명클래스에 생성된 메소드나 필드는 익명클래스 밖에서는 접근할 수 없다.
    • Person p = new Person() {
          String name = "Kim";
          public void callMe() {
              System.out.println("Call callMe method");
          }
          @Override
          void whoAmI() {
              System.out.println("나는 " + name + " 이다.");
          }
      };
      //p.callMe(); //실행되지 않는다. 에러.
      p.whoAmI();
      • callme() 메소드는 익명클래스에서 만들어진 클래스이다.

※ 익명클래스 알고가기

  • 익명클래스는 매개변수로 전달이 가능하다.
    • public static void walk2(Person p) {
          p.whoAmI();
      }
    • walk2(new Person(){
          String name = "Lee";
          @Override
          void whoAmI() {
              System.out.println("나는 " + name + " 이다.");
          }
      });
  • 인터페이스도 익명구현클래스로 만들면 편하게 사용이 가능하다.
    • public interface Remocon {
          public void on();
          public void off();
      }
    • public class Machine {
          Remocon tv = new Remocon() {
              @Override
              public void on() {
                  System.out.println("TV을 켭니다");
              }
              @Override
              public void off() {
                  System.out.println("TV을 끕니다.");
              }
          };
      }
    • 실행은 아래와 같다.
      • Machine machine = new Machine();
        machine.tv.on();   //TV를 켭니다.
        machine.tv.off();  //TV를 끕니다. 
  • 익명클래스를 메소드나 익명클래스를 매겨변수로 받는 메소드로 만들 수 있다. (두가지 모두 구현)
    • public void radioWork() {
          Remocon radio = new Remocon() {
              @Override
              public void on() {
                  System.out.println("Radio을 켭니다");
              }
              @Override
              public void off() {
                  System.out.println("Radio을 끕니다.");
              }
          };    
          radio.on();
          radio.off();
      }
      
      public void machineWork(Remocon remocon) {
          remocon.on();
          remocon.off();
      }
    • machine.radioWork();
      machine.machineWork(new Remocon(){
          @Override
          public void on() {
              System.out.println("컴퓨터를 켭니다.");
          }
          @Override
          public void off() {
              System.out.println("컴퓨터를 켭니다.");
          }
      });

'Java > java' 카테고리의 다른 글

java :) Arrays의 다양한 메소드 정리하기  (0) 2022.04.23
java :) StringBuffer  (0) 2022.04.23
java :) interface와 abstract의 공통점과 차이점  (0) 2022.04.22
java :) generic method  (0) 2022.03.14
java :) generic class의 이해  (0) 2022.03.13