본문 바로가기
자바

[Java] Nested Class, 클래스 안의 클래스

by 책 읽는 개발자_테드 2021. 8. 27.
반응형

학습할 것

· Nested Class란?

 · Static nested 클래스

     - StaticNested 클래스 객체 생성

     - StaticNested 클래스의 사용이유

 ·  내부(inner or local inner) 클래스와 익명 클래스(anonymous)

     - 내부 클래스

     - 내부 클래스 객체 생성

     - 내부 클래스의 사용이유

     - 익명 클래스

 · Static Nested 클래스와 내부 클래스에서 참조 가능한 변수


 

Nested Class란?

 · 클래스 안에 들어있는 클래스

 · 존재이유: 1. 한 곳에서만 사용되는 클래스를 논리적으로 묶어서 처리하기 위해

                 2. 캡슐화를 위해(내부 구현을 감추고 싶을 때)                 3. 소스 가독성가 유지보수성을 높이기 위해

ex) 자바 기반의 UI 처리를 할 때 사용자 입력, 외부의 이벤트에 대한 처리

 · Nested 클래스의 종류: Static nested class, inner class (local, anonymous)

https://www.geeksforgeeks.org/local-inner-class-java/

 

Static nested 클래스

public class OuterOfStatic {
    static class StaticNested{
        private int value=0;
        public int getValue(){
            return value;
        }
        public void setValue(int value){
            this.value=value;
        }
    }
}

 

 · 위 코드를 컴파일하면, 내부의 Nested 클래스는 별도로 컴파일하지 않아도 자동으로 컴파일된다. 컴파일 결과

 ·  컴파일 결과를 보면 Nested 클래스를 감싸고 있는 이름 뒤에 $를 붙인 후 Nested 클래스의 이름이 나오고, 별도의 클래스 파일로 만들어진다.

 

StaticNested 클래스 객체 생성

감싸고 있는 클래스 이름 뒤체 .(점)을 찍고 사용

public class NestedClassClient {
    public static void main(String[] args){
        NestedClassClient client = new NestedClassClient();
        client.makeStaticNestedObj();
    }
    public void makeStaticNestedObj(){
        OuterOfStatic.StaticNested staticNested = new OuterOfStatic.StaticNested();
        staticNested.setValue(3);
        System.out.println(staticNested.getValue());
    }
}

 

StaticNested 클래스의 사용이유

 · 클래스를 묶기 위해 사용

 · 겉 보기에는 유사하지만, 내부적으로 구현이 달라야할 때

 · 예시: 하나의 프로그램에서 School 클래스, University 클래스, Student 클래스가 존재할 때 Student가 School의 학생인지 University의 학생인지 불분명해진다. 이럴 때 StaticNested 클래스를 사용할 수 있다.

public class University {
    static class Student{

    }
}

 

public class School {
    static class Student{

    }
}

 

내부(inner or local inner) 클래스와 익명 클래스(anonymous)

내부 클래스

 ·  StaticNested 클래스에서 static 선언을 지운 형태

public class OuterOfInner {
     class Inner{
        private int value=0;
        public int getValue(){
            return value;
        }
        public void setValue(int value){
            this.value=value;
        }
    }
}

 

내부 클래스 객체 생성

 · Inner 클래스를 감싸는 Outer 클래스 객체를 먼저 생생한 후, 해당 outer 객체를 통해 Inner 클래스의 객체를 만듦

public class NestedClassClient {
    public static void main(String[] args){
        NestedClassClient client = new NestedClassClient();
        client.makeInnerObject();
    }

    public void makeInnerObject(){
        OuterOfInner outer = new OuterOfInner();
        OuterOfInner.Inner inner = outer.new Inner();
        inner.setValue(3);
        System.out.println(3);
    }
}

 

내부 클래스의 사용이유

 · 캡슐화를 위해 

 · 하나의 클래스에서 어떤 공통적인 작업을 수행하는 클래스가 필요한데 다른 클래스에서는 그 클래스가 전혀 필요 없을 때

 · 예시: GUI관련 프로그램 개발 (리스너, 버튼 클릭 또는 키보드 입력 등 이벤트 발생시 해야 하는 작업 정의)

 

익명 클래스

 · 이름이 없는 클래스

 

예시 - 버튼 처리

public class MagicButton {
    public MagicButton(){

    }
    private EventListener listener;
    public void setListener(EventListener listener){
        this.listener=listener;
    }
    public void onClickProcess(){
        if(listener!=null){
            listener.onClick();
        }
    }
}

 

public interface EventListener {
     void onClick();
}

 

public class AnonymousClient {
    public static void main(String args[]){
        AnonymousClient client = new AnonymousClient();
        client.setButtonListener();
    }
    public void setButtonListener(){
        MagicButton button = new MagicButton();
        button.setListener(new EventListener() {
            @Override
            public void onClick() {
                System.out.println("Magic Button Cliecked");
            }
        });
        button.onClickProcess();
    }
}

 

· AnonymousClient 클래스의 setButtonListener() 메소드에서 button 객체의 setListener() 메소드를 보면, new EventListener()로 생성자를 호출한 후 바로 중괄호를 열어 onClick() 메소드를 구현했다. 이렇게 구현한 것이 익명 클래스다.

 

 · 클래스 이름, 객체 이름이 없으므로 다른 클래스나 메소드에서 참조, 재사용 불가

 · 익명 클래스의 장점: 메모리 사용량 , 애플리케이션 시작 시간↓ (클래스를 만들고, 호출하면 그 정보가 메모리에 올라가므로)

 

Static Nested 클래스와 내부 클래스에서 참조 가능한 변수

· Static Nested 클래스를 외부 클래스의 static 변수만 접근 가능하고, 내부 클래스는 외부 클래스의 모든 변수에 접근 가능하다.

public class NestedValueReference {
    public int publicInt=0;
    protected int protectedInt=1;
    int justInt=2;
    private int privateInt=3;
    static int staticInt=4;
    static class StaticNested{
        public void setValue(){
            staticInt=14;
        }
    }
    class Inner{
        public void setValue(){
            publicInt=20;
            protectedInt=21;
            justInt=22;
            privateInt=23;
            staticInt=24;
        }
    }
    public void setValue(){
        EventListener listener = new EventListener() {
            @Override
            public void onClick() {
                publicInt=20;
                protectedInt=21;
                justInt=22;
                privateInt=23;
                staticInt=24;     
            }
        };
    }
}

 

· 외부 클래스에서 Static Nested 클래스와 내부 클래스의 인스턴스 변수에 접근도 가능하다. private라고 해도 모두 접근할 수 있다.

public class ReferenceAtNested {
    static class StaticNested{
        private int staticNestedInt=99;
    }
    class Inner{
        private int innerValue=100;
    }
    public void setValue(int value){
        StaticNested nested = new StaticNested();
        nested.staticNestedInt=value;
        Inner inner=new Inner();
        inner.innerValue=value;
    }
}

 

출처

자바의신

반응형

댓글