ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java | Inner Class 내부 클래스 & Anonymous class 익명 클래스
    JAVA/JAVA 2020. 2. 4. 17:25

    Inner Class 내부 클래스

    클래스 내부에 작성하는 클래스

    • 내부 클래스는 외부 클래스의 접근 제어자에 상관 없이 멤버변수, 메소드에 접근 가능
    • 외부 클래스에서 내부 클래스에 접근하기 위해서는 내부 클래스 객체를 생성해야 함

    이름이 있는 내부 클래스

    내부 클래스에 이름이 있는 경우, 일반 클래스와 동일함
    다른 클래스의 내부에 있다는 점과 main()에서 클래스를 생성하는 방식만 다름

    외부 클래스의 멤버 변수 및 메소드에 편리하게 접근하기 위해 사용


    main() 메소드에서 내부 클래스 객체 생성법

    Outer클래스명.Inner클래스명 Inner객체명 = Outer객체명.new Inner클래스명()
    
    // 외부 클래스 객체 생성
        Outer out = new Outer();
    // 내부 클래스 객체 생성
        Outer.Inner in = out.new Inner();

    사용례

    package j200204;
    
    public class Outer {
        // 멤버 변수
        int a;
    
        // 생성자
        public Outer() {
            // 멤버 변수 초기화
            a = 10;
        }
    
        public void aa() {
            System.out.println("aa 메소드 호출");
            // 메소드 내부에서 내부 클래스 객체 생성 및 메소드 호출
            Inner in = new Inner();
            in.cc();
        }
    
        public void bb() {
            System.out.println("bb 메소드 호출");
        }
    
        // ========= Inner Class =========
        public class Inner {
            // 내부 클래스 멤버 변수
            int ax;
    
            // 내부 클래스 생성자
            public Inner() {
                ax = 15;
            }
    
            // 내부 클래스 메소드
            public void cc() {
                System.out.println("내부 클래스 cc 메소드 호출");
                System.out.println("외부 a: " + a + ", 내부 ax: " + ax);
                bb();
            }
        }
    
        public static void main(String[] args) {
            // Outer 클래스 객체 생성
            Outer out = new Outer();
    
            // main()에서 Inner 클래스 생성
            Outer.Inner oi = out.new Inner();
            
            System.out.println("==내부 클래스 멤버 변수==");
            
            // 내부 클래스 객체 oi의 멤버 변수 ax출력
            System.out.println("ax: " + oi.ax);
            
            System.out.println("====메소드 호출====");
            
            // 외부 클래스 메소드 호출
            // 메소드 호출 순서 out.aa -> in.cc -> out.bb
            out.aa();
            
             /*
             ==내부 클래스 멤버 변수==
             ax: 15
             ====메소드 호출====
             aa 메소드 호출
             내부 클래스 cc 메소드 호출
             외부 a: 10, 내부 ax: 15
             bb 메소드 호출
             */
        }
    
    }

    Anonymous inner class 익명 내부 클래스

    클래스의 이름이 없는 경우로
    상속받은 추상클래스 또는 인터페이스를 바로 객체로 생성해서 반환함

    • 단 하나의 추상 클래스 또는 단 하나의 인터페이스를 바로 생성할 수 있음
    • 클래스 마지막에 세미콜론(;)을 사용해서 익명 내부 클래스가 끝났다는 것을 표현
    • 인터페이스나 추상 클래스 자료형으로 변수를 선언한 후
      익명 내부 클래스를 생성해 변수에 대입할 수 있음
    • 메소드 내부에 작성해서 메소드 반환형을 해당 인터페이스/추상클래스로 지정할 수도 있음
    • 인터페이스와 추상 클래스 내부의 모든 추상 메소드를 반드시 오버라이딩 해야 함

    형식

    new 부모 추상클래스명(){
        // 부모 추상클래스 추상 메소드 오버라이딩
    };
    
    new 부모 인터페이스명(){
        // 부모 인터페이스 메소드 오버라이딩
    };

    사용례

    OuterInter.java

    OuterInter 인터페이스가 선언된 파일

    package j200204;
    
    public interface OuterInter {
    
        public void interPrint();
    
    }

    OuterInner.java

    추상 클래스 Abs를 선언하고
    외부 클래스 OuterInner 내부에 추상 클래스 및 인터페이스 객체 생성
    package j200204;
    
    // 추상 클래스 선언
    abstract class Abs {
    
        // 추상 메소드
        abstract public void absPrint();
    
        // 일반 메소드
        public void print() {
            System.out.println("추상 클래스 일반 메소드 호출");
        }
    }
    
    // 외부 클래스
    public class OuterInner {
    
        // 추상 클래스 상속 내부 익명 클래스 객체 생성
        // 추상 클래스를 상속했기 때문에 자료형은 추상 클래스를 따름
        Abs abs = new Abs() {
            public void absPrint() {
                System.out.println("추상 클래스 상속 내부 익명 클래스");
            }
        };
    
        // 인터페이스 구현 내부 익명 클래스 객체 생성
        // 인터페이스를 구현했기 때문에 자료형은 인터페이스를 따름
        OuterInter oi = new OuterInter() {
            public void interPrint() {
                System.out.println("인터페이스 구현 내부 익명 클래스 ");
            }
        };
    
        public static void main(String[] args) {
    
            // 외부 클래스 객체 생성
            OuterInner outin = new OuterInner();
    
            // 외부 클래스 객체에서 인터페이스 객체의 재정의된 interPrint() 메소드 호출
            outin.oi.interPrint();
    
            // 추상 클래스 객체의 재정의된 absPrint() 메소드 호출
            outin.abs.absPrint();
    
            // 추상 클래스 객체의 일반 메소드 역시 호출 가능
            outin.abs.print();
            
            /*
            인터페이스 구현 내부 익명 클래스 
            추상 클래스 상속 내부 익명 클래스
            추상 클래스 일반 메소드 호출
            */
        }
    
    }

    클래스 내부에 또 다른 클래스를 작성하는 내부 클래스와
    내부 클래스에 이름이 없는 경우인 익명 내부 클래스에 대해 알아보았습니다.

    이름이 있는 내부 클래스의 경우 외부 클래스의 멤버 변수 및 메소드에 보다 편리하게 접근하기 위해 많이 사용되고,

    익명 내부 클래스의 경우 이전에 GUI 구현시 많이 사용되었다고 합니다.

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

    Java | Exception 예외  (0) 2020.02.05
    Java | Object Type Casting 객체 형 변환 & Instanceof  (0) 2020.02.05
    Java | String Method(2) & Character Method  (0) 2020.02.03
    Java | Interface  (0) 2020.02.03
    Java | Call by Value & Call by Reference  (0) 2020.01.31

    댓글

Designed by Tistory.