중첩클래스

YongJun·2023년 9월 14일

JAVA

목록 보기
18/24
post-thumbnail

중첩클래스

다른 클래스 내부에 정의 되는 클래스를 중첩클래스(nested class)라고 한다.
중첩클래스는 독립적으로 오브젝트로 만들어질 수 있는 스태틱 클래스(static class)와 자신이 정의된 클래스의 오브젝트 안에서만 만들어질 수 있는 내부 클래스(inner class)로 구분된다.

내부클래스는 다시 범위에 따라 세 가지로 구분된다.
멤버필드처럼 오브젝트 레벨에 정의되는 멤버 내부 클래스(member inner class)와 메소드 레벨에서 로컬변수를 선언하여 사용하듯 선언된 메소드 내에서만 사용 가능한 로컬 내부 클래스(local inner class), 그리고 이름을 갖지 않는 익명 내부 클래스(anonymous inner class)다.

class 클1{
	static class 클2{} //스태틱 클래스(static class)
	class 클2 {} //내부 클래스(inner class), 멤버 내부 클래스(member inner class)
	메소드() {
			class 클3 {} //로컬 내부 클래스(local inner class)
	}
	객체생성 {} //익명 내부 클래스(anonymous inner class)
}
  • Member Inner Class
    내부 클래스는 외부 클래스의 모든 멤버에 접근 가능
    하지만 외부 클래스는 내부 클래스의 멤버에 접근 불가능
    단, 내부 클래스로 객체를 선언하면 접근 가능하다.

  • local inner class
    메소드(접근 제어 지정자를 가질 수 없다) 안에 정의되는 클래스, abstract 또는 final로만 지정할 수 있다.
    외부 클래스의 인스턴스 변수뿐만 아니라 메소드의 지역 변수에도 접근할 수 있다.
    하지만 지역 변수는 반드시 final로 선언되어야 한다.

예제(맴버 내부 클래스)

package nested;

public class Outer {
	private String name; //외부 클래스(Outer)의 인스턴스 변수
	
	public void output() {
		Inner in = new Inner(); //내부 클래스(Inner)의 인스턴스 변수(age)를 사용하기 위해서 내부 클래스(Inner)객체 선언
								//Outer -> Inner 접근 X, 객체 생성 시 가능
		System.out.println("이름 = " + this.name + "\t나이 = " + in.age);
	}
	
	class Inner{
		private int age;
		
		public void disp() {
			System.out.println("이름 = " + Outer.this.name +"\t나이 = " + this.age);
			//inner class에서 outer class에 있는 private variable에 접근 가능
		}
		
	}
	
	public static void main(String[] args) {
		Outer ou = new Outer();
		ou.name = "홍길동";
		System.out.println("이름 = " + ou.name);
		System.out.println();
		ou.output();
		System.out.println();
		
		//Inner in2 = new Inner(); // inner class로만 만들 수 없음
		//outer class 내부에 inner class memory allocation(할당)
		//내부 클래스(Inner)의 객체는 외부 클래스(Outer)의 객체가 먼저 생성되어 있어야 생성할 수 있다.
		Outer.Inner in2 = ou.new Inner(); 
		in2.age = 20;
		in2.disp();
		System.out.println();
		
		Outer.Inner in3 = ou.new Inner();
		in3.age = 30;
		in3.disp();
		System.out.println();
		
		/*
		Outer 클래스의 내부 클래스인 Inner 클래스의 인스턴스를 생성하는 코드
		내부 클래스는 외부 클래스의 인스턴스를 통해 생성되므로, new Outer().new Inner() 구문에서 Outer()로 생성한 Outer 클래스의 인스턴스를 사용하여 Inner 클래스의 인스턴스를 생성합니다. 
		이렇게 생성된 Inner 클래스의 인스턴스는 Outer 클래스의 인스턴스와 연관이 있습니다. 
		이러한 연관성으로 인해, Inner 클래스는 Outer 클래스의 멤버 변수 및 메서드에 접근할 수 있습니다.
		 */
		Outer.Inner in4 = new Outer().new Inner();
		//in4.name = "코난"; //error (클래스 안에서만 접근 가능)
		in4.age = 35;
		in4.disp();
		System.out.println();
		
	}

}
/*
이름 = 홍길동

이름 = 홍길동	나이 = 0

이름 = 홍길동	나이 = 20

이름 = 홍길동	나이 = 30

이름 = null	나이 = 35
*/

예제(익명 내부 클래스)

package nested;

public interface InterA {
	public abstract void aa();
	public void bb(); //abstract생략
}
package nested;

/*
추상메소드가 없는 추상클래스를 의미상의 추상클래스라고 한다.
의미상의 추상클래스의 메소드는 모두 빈body로 되어 있다.
 */
public abstract class AbstractExam { 
	public void cc() {} //빈 body
	public void dd() {} 
}
package nested;

//추상클래스
public abstract class AbstractTest { //POJO 형식
	String name;

	public String getName() {
		return name;
	}

	public abstract void setName(String name);  //추상메소드
	
}
//추상메소드가 있으면 반드시 해당 클래스도 추상클래스여야 한다.
package nested;

public class AbstractMain {
	
	public static void main(String[] args) {
		/*
		추상클래스는 자신의 클래스로 메모리 생성을 할 수 없다
    	=> 생성하려면
     	가. 추상클래스를 상속 했을때, Sub Class를 이용(반드시 Sub Class가 추상메소드를 Override 해야 한다)
     	나. 메소드 이용
     	다. 익명 클래스 이용
		*/
		
		//추상클래스를 상속(extends), 인터페이스를 구현(implements) 안했는데도 추상클래스와 인터페이스를 다른 클래스에서 메모리 생성이 가능한가?? -> 가능
		
		//다.
		AbstractTest at = new AbstractTest() { //익명 내부 클래스를 이용하여 추상클래스를 다른 클래스에서 메모리 생성(인스턴스화, 객체생성)
			
			public void setName(String name) { //자식 클래스가 아닌데 꼭 오버라이드를 해줘야 하나? -> Yes
				this.name = name;
			}
		};
		
		InterA in = new InterA() { //익명 내부 클래스를 이용하여 인터페이스를 다른 클래스에서 메모리 생성(인스턴스화, 객체생성)
			//인터페이스를 구현(implements)한 클래스가 아니여도 인터페이스 객체를 생성하면 추상메소드를 오버라이드 해줘야한다.
			public void aa() {} 
			public void bb() {}
		};
		
		//다.
		AbstractExam ae = new AbstractExam() { //익명 내부 클래스
			//추상메소드가 없기 때문에 원하는 메소드를 골라서 Override
		};
		
	}

}
//익명 클래스도 내부 클래스와 같이 필드와 다른 메소드들을 정의할 수 있다, 다만 메소드 안에 정의되는 지역 변수 중에서는 final로 선언된 변수만 사용이 가능하다.
profile
개(발자어)린이

0개의 댓글