프로그래밍/Java 공부

Java_Inner Class 내부 클래스

개발계발게발 2021. 6. 22. 17:18
반응형

Java_Inner Class 내부 클래스

클래스 내부에 또 다른 클래스


클래스 내부에 선언된 클래스 = 두 클래스가 서로 긴밀한 관계


장점

내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근 가능
캡슐화, 코드의 복잡성을 줄여준다.
  
내부 클래스 : 두 클래스가 긴밀하고 , 내부 클래스는 잘 사용되지 않는 것.

 

 

Inner Class 종류


스테틱 클래스

  • 외부 클래스의 멤버 변수 선언 위치에 선언, static 멤버처럼 다뤄진다.
  • 주로 외부 클래스의 static멤버, 특히 static메소드에서 사용될 목적으로 선언

 
멤버 클래스

  • 외부 클래스의 멤버 변수 선언 위치에 선언
  • 외부 클래스의 인스턴스 멤버처럼 사용
  • 주로 외부 클래스의 인스턴스 멤버들과 관련된 작업에서 사용한다.

 

지역 클래스

  • 외부 클래스의 메소드나 초기화 블럭 안에서 선언. 선언된 영역 내부에서만 사용

 

익명 클래스

  • 클래스 선언과 객체의  생성을 동시에 하는 이름 없는 클래스(일회용)

 

 

스테틱 클래스(Static Class)

  • class앞에 static이 붙은 것이 차이점
  • static이 붙었기 때문에 객체 생성없이 사용 가능.
  • 클래스의 static 변수처럼 사용된다.
  • 외부 클래스와 내부 클래스는 다르게 동작
  • 외부 클래스와 내부 클래스의 멤버가 private라도 상호 접근 가능
  • 경로만 지정된다면 단독으로 직접 사용할 수 있다.
public class StaticClass01 {
	private int num = 1;	//객체 생성, 외부 X
	int sc = num;	// 객체 생성, 외부 O
	private static int outterSI = 0;	//클래스명. 객체X, 외부X
	
	public static class SInner{
		private int innerMember = 200;
		private static int innerSm = 300;
		final int LV = 100;
		public static void outterMethod() {
			System.out.println(SInner.innerSm);
		}		
		
		public static void innerMethod() {
			System.out.println("static 클래스 내부 static 메소드");
		}
		
		public void innerM() {
			System.out.println("static 클래스 내부 클래스");
			System.out.println("this.innerSM " + this.innerSm);
			//System.out.println("sc " + sc); 호출 불가
			System.out.println("outterSI " + outterSI);
		}
	}
	public static void main(String[] args) {
		StaticClass01 staticClass01 = new StaticClass01();
		StaticClass01.SInner si = new SInner();
		StaticClass01.SInner si2 = new StaticClass01.SInner();
		
		si.innerMethod();
		si.innerM();
		System.out.println(si.innerMember);
		System.out.println(si.LV);
		
		StaticClass01.SInner.innerMethod();
		//StaticClass01.SInner.innerM(); 객체 생성 후 호출
		
		//AAA객체 생성
		AAA aaa = new AAA();
		//System.out.println(aaa.BBB..);//불가
		//System.out.println(AAA.BBB.); // 안보임
		AAA.BBB bbb = new AAA.BBB();
		//bbb.number2 가능
	}
}

class AAA{
	private static int innerNum = BBB.number;//접근가능
	private static int outternum = 100;
	
	static class BBB{
		private static int number = 10;
		int number2 = outternum;	//외부의 것도 접근 가능
	}
}

 

멤버 클래스(Member Class)

  • 멤버 클래스와 static클래스는 외부 클래스의 멤버 변수와 같은 위치에 선언된다.
  • 또한 멤버 변수와 같은 성질을 가진다.
  • 정적 클래스 static이 아닌 경우 (static선언이 없으면) 내부 클래스라고 부른다.
  • 내부 클래스는 클래스 내에 선언되므로 인스턴스 속성 변수처럼 활용된다. (즉 메소드 {} 안에서만 유효)
  • 인스턴스 변수는 클래스 내에서 선언되지만 메소드 밖에서, 생성자 밖에서, 다른 블록 밖에서 선언된다.                (이 경우 반드 시 초기화 필요)
  • 내부 클래스는 외부 클래스의 멤버를 활용할 수 있지만 외부 클래스는 내부 클래스의 멤버 변수를 활용할 수 없다.
  • 또한 static이 붙은 메소드 내에서는 내부 클래스의 객체 선언X
public class MemberClass01 {
	private int outerDf = 10;
	private static int osi = 55;
	int number = 777;
	
	void outerMethod() {
		System.out.println(number);
		System.out.println(osi);
		System.out.println(this.osi);
		System.out.println(outerDf);
	}
	
	static void outterSM() {
		System.out.println(osi);
//		System.out.println(number); 호출 불가
	}
	
	public class InnerClass{
		private int x = 100;
		int innerDf = 100;
		static final int ISI = 123;
		
		public void innerMethod() {
			int imnum = osi;	//외부 클래스 private static int osi = 55;
			System.out.println(x);
			System.out.println(innerDf);
			System.out.println(ISI);
			System.out.println(number);
			System.out.println(outerDf);
		}		
	}
	public static void main(String[] args) {
		MemberClass01 memberClass01 = new MemberClass01();
		//MemberClass01.InnerClass in = new MemberClass01.InnerClass();
		MemberClass01.InnerClass in = memberClass01.new InnerClass();
		in.innerMethod();
	}
}

 

지역 클래스(Local Class)

 

  • 메소드 안에 선언한 클래스
  • 선언한 메소드 내에서만 사용하기 위해서 내부에 선언
  • 메소드 안에서만 지역변수처럼 클래스를 활용하므로 메소드의 실행이 끝나면 지역 클래스는 제거된다.
  • 외부에서 인스턴스를 생성할 수 없다.
  • 또한 static을 사용할 수 없다.
  • instance 변수 또는 메소드는 사용할 수 있다.
  • final 지역변수(상수처리)하거나 매개변수는 지역 클래스의 메소드에서 접근 가능
     
  • 객체를 생성해서 활용해야 한다.
  • 컴파일하면 외부 클래스$숫자+로컬 클래스명. class로 만들어진다.
  • 숫자는 서로 다른 메소드인 경우 같은 이름의 클래스가 존재할 수 있기 때문에 구분하기 위해서 붙인다.
public class LocalClass01 {
	private int a = 10;
	final int LV = 100;
	
	void method() {
		int in = 100;
		final int inD = 1000;
		
		class LocalClass{
			int no = 99;
			void msg() {
				no = no + 10;
				System.out.println("외부 a " + a);
				System.out.println(LocalClass01.this.a);
				System.out.println(in);
				System.out.println(inD);
			}
		}//LocalClass끝
		//지역 클래스가 선언도니 메소드 안에서 객체를 만든다.
		LocalClass local = new LocalClass();
		local.msg();
	}	
	public static void main(String[] args) {
		LocalClass01 lc = new LocalClass01();
		lc.method();
	}
}

 

익명 클래스(Anonymous Class)

 

  • 클래스 명 없는 클래스
  • 선언과 동시에 인스턴스 생성을 하나로 통합한 클래스
  • 클래스의 인수의 값으로 활용하는 클래스
     
  • 객체를 한번만 사용할 경우 사용한다.
  • 클래스의 선언부가 없기 때문에 이름이 없으므로 생성자를 가질 수 없다.
  • 슈퍼 클래스의 이름이나 구현할 인터페이스를 구현하거나 둘 이상의 인터페이스를 구현할 수 없다.
  • 오직 하나의 클래스를 상속받거나 하나의 인스턴스만 구현 가능하다.
     
  • 코드 블럭에 클래스 선언을 하는 점만 빼고는 생성자를 호출하는 것은 동일하다.
     
  • 객체를 구성하는 new문장 뒤에 클래스의 블럭{}을 첨부하여 몸통을 닫는 형식으로 구성된다.
     
  • new 슈퍼 클래스 또는 인터페이스명(){};
     
  • 객체를 생성한 후에 {}; 즉 메소드를 구현한 블록이 있고 블록 끝에는 세미콜론이 붙는다.
     
  • new 뒤에 오는 생성자명이 기존 클래스명이면 익명클래스가 자동으로 하위클래스가 된다
      
  • 인터페이스인 경우에는 인터페이스를 상속하는 부모 클래스가 Object가 된다.
class AMClass{
	public void method() {
		System.out.println("method");
	}
}

public class Anonymous {
	public static void main(String[] args) {
		//
//		List<String> list = new ArrayList<String>();
//		List<String> list = new List<String>(); 미구현된 메소드 완벽하지 않다.
		//인터페이스는 상속받는 자식 클래스로 생성
		AMClass amc = new AMClass() {
			@Override
			public void method() {
			System.out.println("오버라이드.");
			}			
		};
		amc.method();	// 16행 오버라이드 출력
	}
}

 

 

 

반응형