JAVA 내부클래스

Dev.Shinny·2022년 9월 27일
0

자바의 정석

목록 보기
11/18

내부 클래스(Inner class)

내부 클래스는 클래스 내에 선언된 클래스이다. 클래스 안에 클래스를 선언하는 이유는 두 클래스가 서로 긴밀한 관계에 있기 때문이다.

내부 클래스의 장점

  • 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.
  • 코드의 복잡성을 줄일 수 있다.(캡슐화)
(1)
class A {
	...
}
class B {
	...
}

(2)
class A{
	...
	class B{
    	...
    }
}

B는 내부 클래스(inner class) A는 외부 클래스(outer class)가 된다. 이 때, 내부 클래스인 B는 외부 클래스인 A를 제외하고는 다른 클래스에서 잘 사용되지 않는 것이어야 한다.

내부 클래스의 종류와 특징

내부 클래스의 종류는 변수의 선언 위치에 따른 종류와 같다. 각 내부 클래스의 선언 위치에 따라 같은 선언 위치의 변수와 동일한 유효범위와 접근성을 갖는다.

내부 클래스의 제어자와 접근성


class Outer{

	class InstanceInner{
		int iv = 100;
        static int cv = 150; // 에러! static 클래스가 아니므로, static 변수 선언 불가.
        final static int CONST = 180; // final static은 상수임으로 허용. 
	}
	
	static class staticInner{
		int iv = 200;
		static int cv = 250;
	}
}

public class InnerEx4 {
	public static void main(String[] args) {		
    
		// 스태틱 내부 클래스의 인스턴스는 외부 클래스를 먼저 생성하지 않아도 된다. 
		System.out.println("Outer.StaticInner.cv : "+Outer.staticInner.cv);
		System.out.println("ii.CONST : "+Outer.InstanceInner.CONST);	
        
		Outer.staticInner si = new Outer.staticInner();
		System.out.println("si.iv : "+si.iv);
        
    	// 인스턴스 클래스의 인스턴스 생성하려면 외부 클래스의 인스턴스 먼저 생성해야함.
		Outer oc = new Outer();
		Outer.InstanceInner ii = oc.new InstanceInner();
		System.out.println("ii.iv : "+ii.iv);
	}
}

내부 클래스 중에서 스태틱 클래스만 static 멤버를 가질 수 있다. 다만 final static이 동시에 붙은 변수는 상수(constant)이므로 모든 내부 클래스에서 정의가 가능하다.

인스턴스 멤버는 같은 클래스에 있는 인스턴스 멤버와 static 멤버 모두 직접 호출이 가능하지만, static 멤버는 인스턴스 멤버를 직접 호출할 수 없는 것처럼, 인스턴스 클래스는 외부 클래스의 인스턴스 멤버를 객체 생성 없이 바로 사용할 수 있지만, 스태틱 클래스는 외부 클래스이 인스턴스 멤버를 객체 생성 없이 사용할 수 없다.

class Outer{
	
	int value = 10;	
    
	class Inner {		
		int value = 20;		
        
		void method() {
			int value = 30;
			System.out.println("value = "+value);
			System.out.println("this.value = "+this.value);
			System.out.println("Outer.this.value = "+Outer.this.value);
		}
	}	
}

public class InnerEx5 {
	public static void main(String[] args) {
		
		Outer outer = new Outer();
		Outer.Inner inner = outer.new Inner();
		inner.method();
	}
}

내부 클래스와 외부 클래스에 선언된 변수의 이름이 같을 때 변수 앞에 'this' 또는 '외부 클래스명.this'를 붙여서 서로 구별할 수 있다.

익명 클래스

익명 클래스는 다른 내부 클래스들과 달리 이름이 없다.

클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있는 일회용 클래스다.

new 부모 클래스명() {
	...
}
or
new 구현 인터페이스명() {
	...
}

이름이 없기 때문에 생성자도 가질 수 없으며, 부모 클래스나 구현하고자 하는 인터페이스의 이름을 사용해서 정의하기 때문에 하나의 클래스로 상속받는 동시에 인터페이스를 구현하거나 둘 이상의 인터페이스를 구현할 수 없다.

익명 클래스는 이름이 없기 때문에 '외부 클래스명$숫자.class'의 형식으로 클래스 파일명이 결정된다.

(1)
class Inner{
	public static void main(String [] args){
    	Button b = new Button("start");
        b.addActionListener(new EventHandler());
    }
}

class EventHandler implements ActionLisener{
	public void actionPerformed(ActionEvent e){
    	System.out.println("ActionEvent occurred!");
    }
}

(2)
class Inner{
	public static void main(String [] args){
    	Button b = new Button("start");
        b.addActionListener(new ActionListener(){
        	public void actionPerformed(ActionEvent e){
            	System.out.println("ActionEvent occurred!!!");
            }
        }
    }
}

(1)번 코드를 익명클래스를 이용해 변경한 것이 (2)다.

profile
Hello I'm Shinny. A developer who try to enjoy the challenge.

0개의 댓글