organize/자바

Java 14

001cloudid 2024. 4. 28. 14:55
728x90

내부 클래스

클래스 안의 클래스

 

내부 클래스의 장점

1. 내부 클래스에서 외부 클래스의 멤버를 쉽게 접근할 수 있음.(객체를 생성하지 않고 가능)

2. 코드의 복잡성을 줄 일 수 있음(캡슐화)

 

package chapter07;

class AAA{
	int a = 100;
	BBB bbb = new BBB();
	
}

class BBB{
	void method() {
		AAA aaa = new AAA();
		System.out.println(aaa.a);
	}
	
}

class CCC{
	BBB bbb = new BBB();
	
}

public class Study22Ex1 {

	public static void main(String[] args) {

		BBB bbb = new BBB();
		bbb.method();
		
	}
	
}

 

내부 클래스로 만들기

package chapter07;

class AAA{ //AAA는 BBB의 외부 클래스
	int a = 100;
	BBB bbb = new BBB();

	class BBB{ //BBB는 AAA의 내부 클래스
		void method() {
//			AAA aaa = new AAA();
//			System.out.println(aaa.a);
			System.out.println(a); //객체 생성없이 외부 클래스의 맴버 접근 가능
		}
		
	}
	
}

//class CCC{
//	BBB bbb = new BBB();
//	
//}

public class Study22Ex1 {

	public static void main(String[] args) {

//		BBB bbb = new BBB();
//		bbb.method();
		
	}
	
}

 

내부클래스의 종류와 특징

내부 클래스의 종류와 유효범위는 변수와 동일

  • 인스턴스 클래스 ≒ 인스턴스 변수
  • 스태틱 클래스  ≒ 클래스 변수
  • 지역 클래스  ≒ 지역 변수
  • 익명 클래스 : 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용). 이벤트처리

 

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

package chapter07;

public class Study23Ex1 {
	
	//인스턴스 내부클래스
	class InstanceInner{
		int iv = 100;
//		static int cv = 100; //static 변수 선언 불가
		final static int CONST = 100; //final static은 상수이므로 허용
	}
	
	//static 내부클래스
	static class StaticInner{
		int iv = 200;
		static int cv = 200; //static 클래스만 static멤버를 정의할 수 있음
	}
	
	void method() {
		//지역 내부클래스
		class LocalInner{
			int iv = 300;
//			static int cv = 300; //static 변수 선언 불가
			final static int CONST = 300; //final static은 상수이므로 허용
		}
		
		int i = LocalInner.CONST; //가능
		
	}
	
	public static void main(String[] args) {

		System.out.println(InstanceInner.CONST);
		System.out.println(StaticInner.cv);
//		System.out.println(LocalInner.CONST); //에러. 지역 내부클래스는 메서드 내에서만
		
		
		
	}
	

}

 

package chapter07;

public class Study23Ex2 {
	
	class InstanceInner{}
	static class StaticInner{}
	
	InstanceInner iv = new InstanceInner(); //인스턴스 멤버끼리는 직접 접근가능
	static StaticInner cv = new StaticInner(); //static 멤버끼리는 직접 접근 가능
	
	static void staticMethod() { //static멤버는 인스턴스 멤버에 직접 접근 불가
//		InstanceInner obj1 = new StaticInner();
		StaticInner obj2 = new StaticInner();
	}
	
	void instanceMethod(){ //인스턴스 메서드에서는 인스턴스 멤버와 static멤버 모두 접근 가능
		InstanceInner obj1 = new InstanceInner();
		StaticInner obj2 = new StaticInner();
//		LocalInner iv = new LocalInner(); //지역 내부 클래스는 외부에서 접근할 수 없음
	}
	
	void method() {
		class LocalInner{}
		LocalInner lv = new LocalInner();
	}
	
}

 

package chapter07;

class Outer{
	private int outerIv = 0;
	static int outerCv = 0;
	
	class InstanceInner{
		int iiv = outerIv; //외부 클래스의 private 멤버도 가능(같은 클래스 안)
		int iiv2 = outerCv;
	}
	
	static class StaticInner{
//		int siv = outerIv; //static 클래스는 외부 클래스의 인스턴스 멤버에 접근할 수 없음
		static int scv = outerCv;
	}
	
	void method() {
		int lv = 0; //값이 바뀌지 않는 변수는 상수로 간주
		final int LV = 0; //JDK1.8부터 final 생략 가능
		
		class LocalInner{ //지역 내부 클래스를 감싸고 있는 메서드의 상수만 사용 가능
			int liv = outerIv;
			int liv2 = outerCv;
			//외부 클래스의 지역변수는 final이 붙은 변수(상수)만 접근 가능
			int liv3 = lv; //JDK 1.8부터 에러 X
			int liv4 = LV;
		}
	}
	
}

public class Study23Ex3 {

}

 

package chapter07;

class OuterS23E4{
	
	class InstanceInner{
		int iv = 100;
	}
	
	static class StaticInner{
		int iv = 200;
		static int cv = 300;
	}
	
	void method() {
		class LocalInner{
			int iv = 400;
		}
	}
	
}

public class Study23Ex4 {

	public static void main(String[] args) {

		//1. 외부 클래스의 인스턴스를 생성
		//2. 내부 클래스의 객체 생성
		OuterS23E4 oc = new OuterS23E4();  
		OuterS23E4.InstanceInner ii = oc.new InstanceInner(); //인스턴스를 생성 가능
		
		//외부 클래스의 객체 생성 없이 사용가능
		System.out.println("ii.iv : " + ii.iv);
		System.out.println("OuterS23E4.StaticInner.cv : " + OuterS23E4.StaticInner.cv);
		
		//static 내부 클래스의 인스턴스는 외부 클래스를 먼저 생성하지 않아도 됨
		OuterS23E4.StaticInner si = new OuterS23E4.StaticInner();
		System.out.println("si.iv : " + si.iv);
		
	}

}

 

package chapter07;

class OuterS23E5{
	int value = 10; //OuterS23E5.this.value. 외부클래스의 iv

	class Inner{
		int value = 20; //this.value. 내부클래스 iv
		
		void method1() {
			int value = 30; //lv
			System.out.println("value : " + value);
			System.out.println("this.value : " + this.value);
			System.out.println("OuterS23E5.this.value : " + OuterS23E5.this.value);
		}
	}
}

public class Study23Ex5 {

	public static void main(String[] args) {
		
		OuterS23E5 outer = new OuterS23E5();
		OuterS23E5.Inner inner = outer.new Inner();
		inner.method1();

	}

}

 

익명 클래스

이름이 없는 일회용 클래스. 정의와 생성을 동시에

package chapter07;

public class Study24Ex1 {
	
	Object ivObject = new Object() {
		void method() {} //클래스 내용
	};
	
	static Object cvObject = new Object() {
		void method() {}
	};

}

 

package chapter07;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.EventHandler;

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

public class Study24Ex2 {
	
	public static void main(String[] args) {

		Button b = new Button("Start");
		b.addActionListener(new EventHandler());
		
	}
}

//===================================================================================
//위의 코드를 익명 클래스로 변경
public class Study24Ex2 {
	
	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");
			}
		});
		
	}
}

 

728x90

'organize > 자바' 카테고리의 다른 글

Java 16  (0) 2024.05.01
Java 15  (0) 2024.04.30
Java 13  (0) 2024.04.25
Java 12  (0) 2024.04.24
Java 11  (0) 2024.04.23