중첩클래스

woom·2022년 11월 16일
0

JAVA

목록 보기
10/18
post-thumbnail

🌼 중첩클래스

  • 중첩클래스(Nested Class) : 클래스(OuterClass) 내부에 다른 클래스(InnerClass)를 선언

    • 두개의 클래스가 밀접한 관계에 있을 때 선언하며 캡슐화(필드를 은닉화 처리하여 보호되도록 작업)를 강화하는데 사용
  • 외부클래스에서는 내부클래스로 객체를 생성하여 접근제한자에 상관없이 내부클래스의 필드 또는 메소드 참조 가능

  • 내부클래스에서는 외부클래스의 필드 또는 메소드를 접근제한자에 상관없이 참조 가능


🎀 Q1. 중첩클래스

  • 외부클래스에서 내부클래스의 필드 또는 메소드에 대한 직접적인 참조 불가능

    • 외부클래스에서는 내부클래스로 객체를 생성하여 접근제한자에 상관없이 내부클래스의 필드 또는 메소드 참조 가능
  • 내부클래스에서는 외부클래스의 필드 또는 메소드를 접근제한자에 상관없이 참조 가능

  • 일반 중첩 클래스 : 컴파일 결과를 [외부클래스$내부클래스.class] 파일로 제공

    • 일반 중첩 클래스에서는 static 제한자를 사용하여 필드 또는 메소드 선언 불가능

🐣 예제1 (OuterOne Class)

	private int outerNum;	//필드 선언
	
	public OuterOne() { }	//기본생성자
	
	public OuterOne(int outerNum) {	//생성자 초기화
		super();
		this.outerNum = outerNum;
	}
	public int getOuterNum() {	//getter, setter 메소드 선언
		return outerNum;
	}
	public void setOuterNum(int outerNum) {
		this.outerNum = outerNum;
	}
	public void displayOuter() {//메소드 선언
		System.out.println("outerNum = "+outerNum);
		//외부클래스에서 내부클래스의 필드 또는 메소드에 대한 직접적인 참조 불가능
		//System.out.println("innerNum = "+innerNum);
		
		//외부클래스에서는 내부클래스로 객체를 생성하여 접근제한자에 상관없이
        //내부클래스의 필드 또는 메소드 참조 가능
		InnerOne innerOne=new InnerOne(200);
		System.out.println("innerNum = "+innerOne.innerNum);
	}
	public class InnerOne {
		private int innerNum;//내부클래스 필드 선언
		
		public InnerOne() { }//기본생성자

		public InnerOne(int innerNum) {	//생성자 초기화
			super();
			this.innerNum = innerNum;
		}
		public int getInnerNum() {	//getter, setter 메소드 선언
			return innerNum;
		}
		public void setInnerNum(int innerNum) {
			this.innerNum = innerNum;
		}
		public void displayInner() {//메소드 선언
			System.out.println("innerNum = "+innerNum); }}}

		//내부클래스에서는 외부클래스의 필드 또는 메소드를 접근제한자에 상관없이 참조 가능 
		//System.out.println("outerNum = "+outerNum);
		//displayOuter(); 




🐣 예제2 (OuterOneApp Class)

  • 일반 중첩 클래스로 내부클래스의 직접 객체 생성 불가능
  • 외부클래스의 객체를 이용하여 일반 중첩 클래스의 객체 생성 가능
import nested.OuterOne.InnerOne;//import 자동생성

public class OuterOneApp {
	public static void main(String[] args) {
		OuterOne outerOne=new OuterOne(100);//OuterOne객체생성
		outerOne.displayOuter();//outerNum = 100, innerNum = 200

		//일반 중첩 클래스로 직접 객체 생성 불가능
		//InnerOne innerOne=new InnerOne();

		//외부클래스의 객체를 이용하여 일반 중첩 클래스의 객체 생성 가능
		InnerOne innerOne=outerOne.new InnerOne(300);//InnerOne객체생성
		innerOne.displayInner(); }}//innerNum = 300
        
        



🎀 Q2. 정적 중첩클래스

  • 정적 중첩 클래스 : static 제한자를 사용하여 클래스 선언

    • 정적 중첩 클래스에서는 static 제한자를 사용하여 필드 또는 메소드 선언 가능
  • 내부클래스의 정적필드는 객체 생성 없이 클래스로 접근하여 참조 가능

🐣 예제1 (OuterTwo Class)

public class OuterTwo {
	private int outerNum;	//필드 선언
	
	public OuterTwo() { }	//기본생성자

	public OuterTwo(int outerNum) {	//생성자 초기화
		super();
		this.outerNum = outerNum;
	}
	public int getOuterNum() {	//getter, setter 메소드 선언
		return outerNum;
	}
	public void setOuterNum(int outerNum) {
		this.outerNum = outerNum;
	}
	public void displayOuter() {//메소드 선언
		System.out.println("outerNum = "+outerNum);
		
		//외부클래스에서는 내부클래스로 객체를 생성하여 접근제한자에 상관없이
        //내부클래스의 필드 또는 메소드 참조 가능
		//InnerTwo innerTwo=new InnerTwo();
		//System.out.println("innerNum = "+innerTwo.innerNum);
		//내부클래스의 정적필드는 객체 생성 없이 클래스로 접근하여 참조 가능
		//System.out.println("staticNum = "+InnerTwo.staticNum);
	}
	public static class InnerTwo {
		private int innerNum;//필드선언
		private static int staticNum=300;//정적필드선언
		
		public InnerTwo () { }	//기본생성자

		public InnerTwo(int innerNum) {	//생성자초기화
			super();
			this.innerNum = innerNum;
		}
		public int getInnerNum() {	//getter, setter 메소드 선언
			return innerNum;
		}
		public void setInnerNum(int innerNum) {
			this.innerNum = innerNum;
		}
		public static int getStaticNum() {
			return staticNum;
		}
		public static void setStaticNum(int staticNum) {
			InnerTwo.staticNum = staticNum;
		}
		public void displayInner() {//메소드 선언
			System.out.println("innerNum = "+innerNum);
			System.out.println("staticNum = "+staticNum);
			
			//내부클래스에서는 외부클래스의 필드 또는 메소드 참조 불가능
			// → 외부클래스의 정적필드나 정적메소드는 참조 가능
			//System.out.println("outerNum = "+outerNum); }}}





🐣 예제2 (OuterTwoApp Class)

  • 정적 중첩 클래스는 직접 객체 생성 가능
import nested.OuterTwo.InnerTwo;

public class OuterTwoApp {
	public static void main(String[] args) {
		OuterTwo outerTwo=new OuterTwo(100);//OuterTwo 객체 생성
		outerTwo.displayOuter();//메소드 호출 - outerNum = 100

		//정적 중첩 클래스는 직접 객체 생성 가능
		InnerTwo innerTwo=new InnerTwo(200);
		innerTwo.displayInner(); }}//innerNum = 200, staticNum = 300
        
        
        
        
        

📌 로컬 클래스(Local Class)

  • 메소드 내부에 선언된 클래스로 메소드가 종료되면 자동 소멸
  • final 또는 abstract 제한자만 사용하여 클래스 선언 가능
  • static 제한자를 사용하여 필드 또는 메소드 선언 불가능
  • 선언된 메소드에서만 객체를 생성하여 사용하므로 접근제한자 선언 생략 가능
  • 비동기식 처리를 위한 스레드 객체를 생성하기 위해 사용

  • 외부클래스에서 로컬클래스를 사용하여 객체 생성 불가능

🐣 예제1 (OuterThree Class)

public class OuterThree {
	private int outerNum;//필드 선언
	
	public OuterThree() { }	//기본 생성자
	
	public OuterThree(int outerNum) {//생성자 초기화
		super();
		this.outerNum = outerNum;
	}
	public int getOuterNum() {	//getter, setter 메소드 선언
		return outerNum;
	}
	public void setOuterNum(int outerNum) {
		this.outerNum = outerNum;
	}
	public void displayOuter() {//displayOuter 메소드 선언
		System.out.println("outerNum = "+outerNum);
		
		//외부클래스에서 로컬클래스를 사용하여 객체 생성 불가능
		//InnerThree innerThree=new InnerThree();
	}
	public void local() {	//local 메소드 선언
		class InnerThree {	//로컬클래스(메소드 내부에 선언된 클래스)
			int innerNum;
			
			void displayInner() {
				System.out.println("innerNum = "+innerNum); 
			}
		}
		InnerThree innerThree=new InnerThree();
		innerThree.innerNum=200;
		//System.out.println("innerThree.innerNum = "+innerThree.innerNum);
		innerThree.displayInner(); }}

🐣 예제2 (OuterThreeApp)

public class OuterThreeApp {
	public static void main(String[] args) {
		OuterThree outerThree=new OuterThree(100);
		
		outerThree.displayOuter();//100
		outerThree.local(); }}//200






📌 익명 객체

  • 익명의 내부클래스(Anonymous Inner Class) : 인터페이스를 상속받은 이름이 없는 자식클래스
    • 익명의 내부클래스에서는 반드시 인터페이스의 모든 추상메소드를 오버라이드 선언
    • 인터페이스 대신 추상클래스를 사용하여 익명의 내부클래스로 객체 생성 가능
  • 익명의 내부클래스를 선언하고 자식클래스로 익명객체를 생성하여 인터페이스 참조변수에 저장

🐣 예제1 (Anonymous interface)

public interface Anonymous {
	void display(); }


🐣 예제2 (AnonymousApp)

public class AnonymousApp {
	public static void main(String[] args) {
		//인터페이스를 이용하여 참조변수 생성은 가능하지만 객체 생성 불가능
		//자식클래스로 객체를 생성하여 인터페이스 참조변수에 객체 저장 가능
		//Anonymous anonymous=new Anonymous();
		
		//익명의 내부클래스를 선언하고 자식클래스로 익명객체를 생성하여
       //인터페이스 참조변수에 저장
		Anonymous anonymous=new Anonymous() {
			@Override
			public void display() {
				System.out.println("익명의 내부클래스의 오버라이드 메소드 호출"); }};
				
		anonymous.display(); }}





profile
Study Log 📂

0개의 댓글

관련 채용 정보