JAVA_41_내부클래스

charl hi·2021년 9월 1일
0

JAVA

목록 보기
41/53

내부클래스

  • 클래스 안의 클래스
class A{		//B의 외부클래스
	class B{	//A의 내부클래스
    
    	}
}
  • 내부클래스에서 객체 생성 없이 외부클래스의 멤버들을 쉽게 접근할 수 있다.

  • 코드의 복잡성을 줄인다. 캡슐화(외부에서 직접 접근 X)


  • 이전 방식
class AA{
	int i=100;
	
}

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



public class InnerTest {

	public static void main(String[] args) {
		BB b = new BB();
		b.method();

	}

}

100

-> 내부클래스

class AA{
	int i=100;
	BB b = new BB();	//내부클래스BB 객체 생성
	
	class BB{
		void method() {
//			AA aa = new AA();	
			//없어도 됨! 객체생성없이 외부클래스 멤버 접근 가능
			System.out.println(i);	//aa.i -> i 
		}
	}
}


public class InnerTest {

	public static void main(String[] args) {
//		BB b = new BB();	//에러. 밖에서 내부클래스 직접접근 못함
//		b.method();
		AA aa = new AA();
		AA.BB bb = aa.new BB();	//1. 오 쩜 뉴!!
		bb.method();
		aa.b.method();		//2. 설계도 내 객체 생성

	}

}

100
100


내부클래스 종류

1. 인스턴스 내부클래스

== iv


2. static 내부클래스

== cv

  1. ✨✨✨static내부클래스만 static멤버(변수, 메소드)를 정의할 수 있다!!!

  2. ✨✨static내부클래스에서는 외부클래스의 iv에 접근할 수 없다!!!

  • 인스턴스 내부클래스와 달리 static 내부클래스에선 외부클래스의 iv에 접근할 수 없다.

  • 오류 : Cannot make a static reference to the non-static field ff

  • ffstatic으로 바꾸면 된다.

  1. final static변수는 상수이므로 어느 내부클래스든 허용

3. 지역 내부클래스

== lv

  • 메소드나 초기화블럭 안의 클래스

4. 익명 내부클래스

  • 클래스 선언과 객체생성을 동시에 하는 이름없는 클래스
  • 일회용
  • 이벤트처리에 사용


내부클래스의 제어자

  • 퍼 프로 디 프라이빗 다 가능

final static 상수 접근 방법

  • 내부클래스명.상수명

  • 지역내부클래스의 상수는 안된다.
    -> 👀왜? : 지역내부클래스 안에서만 사용해야 하니까!



public class Ex7_12 {

	InstanceInner ii = new InstanceInner();	//iv쓰려면
	class InstanceInner{
		int iv = 10;
		static int cv = 100;	//????????
		final static int Const = 1000;
	}
	StaticInner si = new StaticInner();		//iv2쓰려면
	static class StaticInner{
		int iv2 = 20;
		static int cv2 = 200;
		final static int Const2 = 2000;
	}
	
	void myMethod() {
		class LocalInner{
			int iv3 = 30;
			static int cv3 = 300;	//???????
			final static int Const3 = 3000;
		}
		System.out.println(LocalInner.cv3);
		System.out.println(LocalInner.Const3);
		LocalInner li = new LocalInner();	//iv3쓰려면
		System.out.println(li.iv3);
	}

	public static void main(String[] args) {
		System.out.println(InstanceInner.cv);
		System.out.println(InstanceInner.Const);
		Ex7_12 ex = new Ex7_12();
		System.out.println(ex.ii.iv);	//안에서도,밖에서도 객체생성해야 가능
		System.out.println();
		
		System.out.println(StaticInner.cv2);
		System.out.println(StaticInner.Const2);
		System.out.println(ex.si.iv2);	//안에서도,밖에서도 객체생성해야 가능
		System.out.println();
		
//		System.out.println(LocalInner.cv3);	//안됨! myMethod()안에서만 가능
		ex.myMethod();

	}

}

100
1000
10

200
2000
20

300
3000
30

👀👀👀👀??????왜지 왜 선언이 되는거지??



  1. ✨내부클래스에서 외부클래스의 private멤버 접근 가능

2. ✨내부클래스에서 외부클래스의 인스턴스 멤버 접근 불가능

나중에 복습하면서 고치자ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ

- 위처럼 아예 접근불가능이므로, 새로운 변수 선언인줄 알고 세미콜론(;)대신 콤마(,)를 넣으라고 오류가 뜬다!

- 👀👀👀👀위엔 접근가능해서 장점이라고 하지 않았나...


  1. ✨✨지역 내부클래스에서 외부메소드의 ①final지역변수 접근 가능
    ② ✨✨✨외부메소드의 지역변수는 무조건 final 상수
class Out {

	void method() {
   		final int lv = 10;	//못바꿈! 상수!!
     
     		class LocalInner {
        		int liv = lv;
        	}
        
    	}

}


내부클래스 접근 방법

class Outer{
	InstanceInner iii = new InstanceInner();
	class InstanceInner{
		int iv = 10;
		static int cv = 100;	//????????
		final static int Const = 1000;
	}
	
	StaticInner sii = new StaticInner();
	static class StaticInner{
		int iv2 = 20;
		static int cv2 = 200;
		final static int Const2 = 2000;
	}
	
	void myMethod() {
		class LocalInner{
			int iv3 = 30;
			static int cv3 = 300;	//???????
			final static int Const3 = 3000;
		}
		LocalInner li = new LocalInner();	//iv3쓰려면
		System.out.println(li.iv3);
		System.out.println(LocalInner.cv3);
		System.out.println(LocalInner.Const3);
	}
}



public class Ex7_15 {

	public static void main(String[] args) {
		//인스턴스내부클래스 사용 방법
		//외부객체를 먼저 생성하고 내부객체를 생성해야 한다!
		Outer o = new Outer();
		Outer.InstanceInner ii = o.new InstanceInner();
		//***인스턴스 내부객체 생성방법
		
		System.out.println(ii.iv);
		System.out.println(o.iii.iv);
		System.out.println(Outer.InstanceInner.cv);		//객체생성없이 가능
		System.out.println(Outer.InstanceInner.Const);	//객체생성없이 가능
		
		//static내부클래스 사용 방법
		//외부객체 생성 안하고 바로 내부객체 생성 가능!
		Outer.StaticInner si = new Outer.StaticInner();
		//***static내부객체 생성방법
		
		System.out.println(si.iv2);
		System.out.println(o.sii.iv2);
		System.out.println(Outer.StaticInner.cv2);		//객체생성없이 가능
		System.out.println(Outer.StaticInner.Const2);	//객체생성없이 가능
		
		o.myMethod();

	}

}

10
10
100
1000
20
20
200
2000
30
300
3000

1. 인스턴스 내부클래스

1) 외부객체 생성 -> 내부객체 생성

Outer o = new Outer();
Outer.InstanceInner ii = o.new InstanceInner();
...
System.out.println(ii.iv);

외부. 내부 내부참조변수 = 🧨외부참조변수. new 내부();

  • 💖💖💖💖💖오 쩜 뉴 !!!

내부참조변수. 멤버

  • 내부참조변수로만 호출!

2) 외부객체 생성 & 설계도에 내부객체 생성

class Outer{
	InstanceInner iii = new InstanceInner();
    	//...
}
...
...

Outer o = new Outer();
System.out.println(o.iii.iv);

외부참조변수. 참조변수2. 멤버


2. static 내부클래스

1) 내부객체 바로 생성

Outer.StaticInner si = new Outer.StaticInner();
...
System.out.println(si.iv2);

외부. 내부 내부참조변수 = new외부 내부();

  • 외부 안에 있는 내부클래스 호출+생성 이라고 생각하면 편함!

내부참조변수. 멤버


2) 외부객체 생성 & 설계도에 내부객체 생성

class Outer{
	StaticInner sii = new StaticInner();
    	//...
}
...
...

Outer o = new Outer();
System.out.println(o.sii.iv2);

외부참조변수. 참조변수2. 멤버


3. static변수와 final static 상수

객체 생성 안하고 클래스로 호출

Outer.InstanceInner.cv
Outer.StaticInner.cv2

외부클래스. 내부클래스. 멤버



내부메소드에서 외부멤버 호출

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



public class Ex7_16 {

	public static void main(String[] args) {
		Outer2 o = new Outer2();
		Outer2.Inner2 i = o.new Inner2();	//이거 꽤나 헷갈린다. 오 쩜 뉴!!!
		i.method();

	}

}

value = 30
this.value = 20
Outer2.this.value = 10
  • this외부클래스명을 이용하기!



Ref

0개의 댓글

관련 채용 정보