본문 바로가기
STUDY/JAVA

InnerClass(내부클래스)

by NOTEEE 2018. 1. 22.

내부클래스

 - 클래스 내에 선언된 클래스이다.

 - 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근이 가능.

 - 복잡성을 줄임.(캡슐화)


내부클래스의 종류

 - 멤버 클래스 

 - 지역 클래스 

 - static 클래스

 - 익명 클래스


각각의 클래스의 구조는 아래와 같다.


public class Outer {
    class MemberInner {} // 멤버 클래스
    static class StaticInner {} // static 클래스
    
    void myMethod() {
        class LocalInner {} // 지역 클래스
    }
}
cs



멤버클래스

class Outer {
      ...
     class Inner {
 
     }
      ...
}
cs

 - 객체를 생성해야만 사용할 수 있는 멤버들과 같은 위치에 정의되는 클래스.


public class MemberInnerClass {
 
    // 내부클래스 정의
    public class Inner {
        public void call() {
            System.out.println("호출");
        }
    }
 
    public static void main(String[] args) {
        // 호출 1
        // MemberInnerClass mic = new MemberInnerClass();
        // Inner inner = mic.new Inner();
        
        // 호출 2
        MemberInnerClass.Inner inner = new MemberInnerClass().new Inner();
        inner.call();
    }
}
cs

 - 보통 메인에서는 외부 클래스를 생성하고 외부 멤버메소드에서 내부 클래스를 호출한다.



Static클래스

public class StaticClass {
    
    int i;
    static int j;
    
    public void instanceOutMethod() {
        System.out.println("instanceOutMethod");
    }
    
    public static void staticOutMethod() {
        System.out.println("staticOutMethod");
    }
    
    static class Static{
        static String name;
        
        public static void staticInMethod(){
            System.out.println("안쪽 메서드");
            StaticClass.j = 100;
            StaticClass.staticOutMethod();
            
            // Static 메소드에서는 Instance 메소드를 사용 할 수 없다.
            // instanceOutMethod();
        }
    }
    
    public static void main(String[] args) {
        // Static의 멤버 사용
        Static.name = "Static";
        Static.staticInMethod();
    }
}
cs

 - 내부클래스에 static을 붙여 정의.

 - static 클래스는 객체화 하지 않고 사용


지역클래스

public class LocalClass {
    
    int outer_i;
    
    public void myMethod(int i, final int j){
 
        final int local_i = 0;
        // int local_j = 0;
        
        class Local {
            
            int k;
 
            public void localMethod() {
 
                System.out.println("바깥클래스의 인스턴스변수" + outer_i);
 
                // final이 붙어있지 않는 파라미터는 사용할 수 없다.
                // System.out.println("파라메터 j =" + i);
                System.out.println("파라메터 j =" + j);
                
 
                // final이 붙어있지 않는 변수는 지역변수에서 사용할 수 없다.
                System.out.println("지역변수 local_i =" + local_i);
                System.out.println("지역클래스의 메소드");
            }
        }
        Local local = new Local();
        local.k = 10;
        local.localMethod();
    }
    
    public static void main(String[] args) {
        LocalClass tl = new LocalClass();
        tl.myMethod(100200);
    }
}
cs

 - 메소드 안에 클래스를 정의.

 - 메소드 내부에만 지역변수처럼 클래스를 사용할 때

 - 지역변수, 파라미터에 final을 붙여야 사용할 수 있다.

 - 메소드 외부에서 사용할 수 없다.


익명클래스

 - 이름이 없는 일회용 클래스

 - 단 하나의 클래스를 상속받거나 단 하나의 인터페이스만을 구현할 수 있다.


 - 예제1

public class AnonymousBean1 {
    private String msg = "익명클래스1";
     
    public String getMsg() {
        return msg;
    }
 
    public void setMsg(String msg) {
        this.msg = msg;
    }
}
cs


public class Anonymous1 {
    // 생성자
    public Anonymous1() {
        print(new AnonymousBean1());
 
        print(new AnonymousBean1() {
            // AnonymousBean1()을 상속받고 재정의 한다.
            // 즉, AnonymousBean1()를 상속받은 익명의 자식클래스다.
            String msg = "익명클래스2";
 
            public String getMsg() {
                return msg;
            }
        });
    }
 
    public void print(AnonymousBean1 m) {
        String msg = m.getMsg(); // AnonymousBean1 클래스의 msg 를 리턴한다.
        System.out.println("msg:" + msg);
    }
 
    public static void main(String[] args) {
        new Anonymous1(); // 생성자만 필요하므로 인스턴스를 저장하지 않아도 된다.
    }
}
cs


 - 예제2

public interface AnonymousBean2 {
     public void stop();
}
cs


public class AnonymousBean3 {
    public void go() {
        System.out.println("AnonymousBean3에 있는 go메소드");
    }
}
cs


public class Anonymous2 {
    
    // AnonymousBean2 인터페이스를 구현
    AnonymousBean2 in_interface = new AnonymousBean2() {
        @Override
        public void stop() {
            System.out.println("익명 내부클래스");
        }
    };
    
    // AnonymousBean3 클래스를 상속받아 재정의
    AnonymousBean3 in_class = new AnonymousBean3() {
        @Override
        public void go() {
            System.out.println("AnonymousBean3에서 재정의한 go 메소드");
        }
    };
 
    public static void main(String[] args) {
        Anonymous2 in = new Anonymous2();
        in.in_interface.stop();    // 익명내부클래스의 메소드 호출 -> 인터페이스
        in.in_class.go();        // 익명내부클래스의 메소드 호출 -> 클래스
    }
}
cs


'STUDY > JAVA' 카테고리의 다른 글

람다표현식2  (0) 2018.01.22
람다표현식1  (0) 2018.01.22
Object클래스  (0) 2018.01.22
예외처리 - 나만의 예외처리 만들기  (0) 2018.01.22
예외처리4  (0) 2018.01.22