[Java] 중첩 클래스

zl존석동

·

2022. 1. 5. 20:44

나만 모르고 나만 본 적 없는 중첩 클래스..

Java 에서 중첩클래스란 무엇일까?


중첩클래스란?

왜 쓸까?

특징

종류

 

 

 

 

 

중첩클래스(Nested Class)란 ??

 

 

 

클래스 안에 또 다른 클래스가 정의되는 것을 말한다.

 

이 때 일반적으로 우리가 정의하던 클래스를 Outer, 그 안에 있는 클래스를 Inner 라고 말할 수 있다.

 

 

 

 

 

중첩클래스를 왜 쓰나??

 

 

한 곳에서만 사용되는 두 클래스들을 논리적으로 그룹화한다.

 

하나의 클래스가 오직 하나의 다른 클래스에서만 유용하다면

 

해당 클래스에 포함되어있는게 더 합리적일 수 있다라는 것입니다.

 

 

웹 또는 앱의 에서 클릭하면 내 통장에 돈이 들어오는 버튼을 구성한다고 해봅시다.

보여지는 버튼 이라는 것이 구성되어 있어야 돈이 들어온다 라는 이벤트를 처리할 수 있을 것이고

돈이 들어온다 라는 이벤트는 이 버튼에서만 동작하고 이 버튼이 없다면 필요 없는 기능입니다.

굳이 이 기능을 다른 곳에 정의해둘 필요가 없겠지요.

이럴 경우 버튼에 대한 화면처리를 Outer 클래스,

해당 버튼에 대한 동작인 이벤트를 Inner 클래스라고 빗대어 표현해볼 수 있지 않을까 합니다.

 

 

캡슐화 정도를 증가시킨다.

 

Outer 클래스의 private 멤버에 대해 Inner 클래스에서 얼마든지 접근할 수 있으면서도

 

외부로부터는 데이터를 숨길 수 있으며 Inner 클래스의 경우 아예 외부로부터 숨겨져있게 된다.

 

또한 Inner 클래스의 경우 Outer 클래스에만 필요한 밀접한 또 다른 (기능+속성) 이 묶여진 것들로써

 

Outer 클래스 내부에 위치한다고 볼 수 있기 때문에 캡슐화 정도를 향상시킨다고 볼 수 있는게 아닌가 생각한다. 

 

 

 

 

중첩 클래스의 특징

 

 

Outer 클래스의 멤버(private 여도)를 Inner 클래스를 자기 것 마냥 사용할 수 있다.

 

static이 아니라면 Inner 클래스는 반드시 Outer 클래스를 통해서만 접근할 수 있다.

 

static이 아니라면 Inner 클래스 내부에는 static 멤버가 올 수 없다.

 

 

 

 

 

 

중첩 클래스 종류

 

 

Member(Inner) 클래스

 

- Outer 클래스의 멤버처럼 정의되는 클래스로 외부 클래스가 인스턴스화 되어야지만 사용이 가능하다.

 

- 인스턴스 변수, 메소드처럼 외부 클래스가 인스턴스화 되어야 의미가 있기 때문에 당연히 Inner 클래스 내부에는 static 멤버를 가질 수 없게 되는 것이다.

 

 

class Outer {
  // inner 클래스에서 멤버변수에 모두 접근할 수 있다.
  public int n = 10;
  protected int n2 = 20;
  int n3 = 30;
  private int n4 = 40;
  static int n5 = 5;
  public void methodOuter() {
    Inner i = new Inner();
    i.methodInner();
  }
  // Inner Class 만드는이유 -> Outer 에서만 사용하는 클래스 필요시  
  class Inner {
    int x = 100;
    // Inner class 는 Static 멤버를 가지지 못한다.
    // static int y = 1;
    public void methodInner() {
      // outer의 private 멤버에도 접근할 수 있따.
      System.out.println(n4);
      System.out.println(n5);
    }
  }
}

 

 

Local Inner 클래스

 

- Outer 클래스의 메소드 내부에 정의된 클래스를 말한다.

 

- 로컬변수처럼 메소드 호출 시 생성되고 종료 시 삭제 된다.

 

 

Static Inner 클래스

 

- Static 으로 정의한 Inner 클래스를 말하며 static 멤버를 포함할 수 있다.

 

- 당연하겠지만 Outer 클래스를 인스턴스로 초기화하지 않아도 Inner 클래스에 접근해서 사용할 수 있다.

 

// Outer 클래스
class Outer2 {
  public int n = 10;
  protected int n2 = 20;
  int n3 = 30;
  private int n4 = 40;
  private static int n5 = 50;

  public void methodOuter() {
    int x = 10;
    // 2. Local Inner Class
    class Inner {
      int z = 200;

      public void methodInner() {
        System.out.println(n4);
      }
    }
  }

  // 3. Static Inner Class
  static class Inner3 {
    int a = 10;
    // Static 사용 가능
    static int b = 15;

    public static void methodInner() {
      System.out.println(n5);
    }
  }
}
public class Main2 {
  
  public static void main(String[] args) {
    Outer2.Inner3.methodInner();
  }
}

 

 

Anonymous 클래스

 

- 익명 클래스는 클래스의 선언과 객체의 생성을 동시에 하는 일회용 클래스를 말한다.

 

- 주로 인터페이스를 구현할 때 사용되며 인터페이스의 이름을 이용해 정의하기 때문에 [상속+인터페이스 or 여러 인터페이스] 를 구현할 수 없고 단 하나의 클래스를 상속받거나 하나의 인터페이스에 대해서만 구현할 수 있다.

 

 

일반적인 이름 있는 클래스에 인터페이스를 받아 구현하게 되는 방법이다.

 

interface Playable {
  void run();
  void runAway();
}

// 이름있는 클래스 만들고 구현하는 예시
class A implements Playable{
  @Override
  public void run() {
    System.out.println("뛰어");
  }
  @Override
  public void runAway() {
    System.out.println("도망쳐");
  }  
}

public class AnonyExam {
  public static void main(String[] args) {
    A a = new A();
    a.run();
  }
}

 

 

위의 코드를 익명 클래스 방법으로 변경하면 다음과 같다. 

 

public class AnonyExam {

  public static void main(String[] args) { 
    Playable p = new Playable() {
      @Override
      public void runAway() {
        System.out.println("익명 달려");
      }
      @Override
      public void run() {
        System.out.println("익명 도망쳐");
      }
    };
    p.run();
  }
}

interface Playable {
  void run();
  void runAway();
}

 

 

 

 

재사용할 필요성이 없이 단 한번만 사용하게 된다면

 

바로 그 위치에서 익명클래스를 통해 딱 한번만 구현함으로써  따로 클래스를 정의하고 기능 내용을 찾아다녀야 하는 번거로움이 없어서 좋을 것 같다.

 

 

 

 

 

 

 

ref

 

 

Nested Classes (The Java™ Tutorials > Learning the Java Language > Classes and Objects)

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated

docs.oracle.com

 

'Java' 카테고리의 다른 글

[Java] Abstract , Interface  (0) 2022.01.09
[Java] 람다식이란  (0) 2022.01.06
[Java] 자바는 Call by Value (feat. C++)  (0) 2022.01.04
[Java] 자바 메모리 구조와 변수 타입  (0) 2021.12.22
[Java] Java 의 동작  (0) 2021.12.20