앞에서의 포스팅은 전부 클래스를 단독으로 사용하는것을 예제로 들었는데 코드를 작성했을때 class안에서 다른 class를 선언한다던가 잘못 복사했을때 내부에 class파일가 여러개 생기는 경우가 종종 있었을것이다.

이것을 자바에선 중첩클래스라고 의미하며 이것에 대해 설명하려고 한다.

 

중첩클래스

중첩 클래스는 클래스 안에서 또다른 클래스가 정의되는것을 말한다.(클래스 안의 클래스)

그리고 이것을 2가지로 나눠서 외부클래스(A), 내부클래스(B)로 나눌수 있다.

//기존클래스
class A{
    int i = 100;
    B b = new B();
}	

class B{
    void method(){
    	A a = new A();
        System.out.println(a.i);
    }
}

class C{
    B b = new B();	//실행가능
    b.method();	//100출력
}

상단의 코드는 클래스를 호출하여 값을 사용하는 코드이다.

이것을 중첩클래스로 바꾼다면 하단과 같은 코드로 변경할수 있다.

//중첩클래스
class A{	//B의 외부클래스
    int i = 100;
    B b = new B();
	
    class B{	//A의 내부클래스
        void method(){
            int a = 200;
            System.out.println(i);	//객체 생성 없이 즉시 외부 클래스 맴버 접근가능
        }
    }
}

class C{
//B b = new B();	//실행불가

//외부클래스의 멤버에 접근하는 방식
//바깥클래스.this.필드OR메서드
    System.out.println(test.this.a);

}

 

class B가 A의 내부로 들어간것을 볼수 있는데 이러한 형태가 중첩클래스의 기본형태이다

그렇다면 굳이 중첩클래스를 사용하는 이유는 무엇일까?

(외부클래스에 종속되어 사용되기 때문에 외부에서 접근이 불가능한 private 접근제어자를 사용한다.)


중첩클래스를 사용하는 이유

1. 외부 클래스의 메서드가 너무 많아 기능별로 분류하기 위하여(개발자가 보고 나중에 유지보수나 활용하기 좋으려고)

2. 선언하려는 클래스가 외부 클래스에 종속적일경우 사용 (얘만 가지고 있는 특수 기믹 또는 특수한 기능 등 -> 마린의 스팀팩, 탱크의 시즈모드 등)

3.특정 클래스를 자신의 클래스 내부적인 용도로만 사용하고자 할때 효율적 -> 만일 다른 클래스에서 내부클래스에 접근하려면 외부클래스를 통하여 접근할수 있다.

중첩클래스의 장점

1. 내부 클래스(B)에서 외부 클래스(A)의 맴버들을 쉽게 접근할수 있다 (객체 생성 없이 사용가능)

2. 코드복잡성(캡슐화) 가능 ->사용하는 이유 1번과 연관

3. 클래스가 타 클래스에 종속적이라면 캡슐화된 클래스들 간의 맴버를 접근할땐 getter와 setter를 사용하여야 하는데 중첩클래스를 사용하는경우 getter와setter를 사용없이 서로의 맴버에 접근이 가능하다.

 


중첩클래스의 종류

중첩클래스는 static으로 선언되지 않은 내부클래스, static으로 선언된 정적클래스로 나뉜다.

내부클래스 - 인스턴스, 지역클래스,익명클래스

인스턴스 클래스(instance class -> IC) - 외부클래스의 맴버변수, 메서드처럼 클래스 정의

스태틱 클래스(static class -> SC) - static키워드를 이용해 클래스가 정의

지역 클래스 (local class -> LC) - 외부클래스의 특정 메서드 안에서 클래스가 정의

익명 클래스 (anonymous calss -> AC) - 익명클래스를 이용해 클래스 정의

//내부클래스 종류
class test{

//인스턴스클래스
    class A{	        
        int inv = 100;
//      static int cv = 100;	                //인스턴스는 static변수를 선언할수 없다.
        final static int CONST = 100;		//final static은 상수이므로 허용된다.
    }

//정적클래스
    static class B{   
        int iv = 200;
        static int cv = 200;	                //static클래스만 static맴버를 정의할수 있다.
    }

//로컬클래스
    void method(){	        
        class C{
            int iv = 300;    
//    	    static int cv = 300;	        //static 클래스만 static맴버 정의가능
            final static int CONST = 300;	//fianl static은 상수이므로 허용!
        }
    }
    

//메인함수    
    public static void main(String args[]){
    	System.out.println(A.CONST);
    	System.out.println(B.cv);
    	System.out.println(C.CONST);	//지역클래스는 메서드 내에서만 허용
    }
    
}

static은 객체생성 없이 사용이 가능해야 하는데 정적클래스를 제외한 나머지는 모두 객체생성을 필요로 하기 때문이다 ,

단, fianl은 상수이므로 사용이 가능하다.

종류 사용불가 선언위치 비고
인스턴스클래스 static 외부클래스와 맴버변수 사이에 선언 외부클래스의 인스턴스 맴버와 관련된 작업
스태틱
클래스
(정적
클래스)
- 외부클래스와 맴버변수 사이에 선언 staic은 메서드,변수,클래스 모두 상위에 존재하는 클래스의 인스턴스를 필요로 하지 않는다.
로컬
클래스
(지역
클래스)
static,
접근
제한자
외부 클래스의 메서드 내부, 초기화 블럭 내부 메모리 실행이 끝나도 힙메모리에 계속 존재,
파라미터는 로컬클래스에 복사해서 사용
익명
클래스
- 외부 클래스의 메서드 내부에 선언 상속 또는 생성과 동시에 재정의하여 사용
-> 주로 1회용 목적으로 사용

 

익명클래스 

// 인터페이스
interface IAnimal {
    public String bark(); // 추상 메소드
    public String run();
}

public class Main {
    public static void main(String[] args) {
        // 인터페이스 익명 구현 객체 생성
        IAnimal dog = new IAnimal() {
            @Override
            public String bark() {
                return "개가 짖습니다";
            }
            
            @Override
            public String run() {
                return "개가 달립니다";
            }
        };	//뒤에 세미콜론을 붙여줘야 한다
        
        // 인터페이스 구현 객체 사용
        dog.bark();
        dog.run();
    }
}

'JAVA' 카테고리의 다른 글

동일성(identity)과 동등성(equality)  (0) 2023.02.26
예외에 관하여  (0) 2023.02.24
생성자(Constructor)와 this  (0) 2023.02.06
오버로딩  (0) 2023.02.02
매개변수  (0) 2023.01.31

+ Recent posts