내부(inner) 클래스와 익명 클래스

msung99·2022년 2월 14일
0


내부 클래스

클래스 내부에 또 다른 클래스를 선언하는 것

  • 두 클래스의 멤버에 쉽게 접근할 수 있다.
public class OuterClass{
  int num = 10;
  String str1 = "Java";
  static String my_str = "world";
  
  public OuterClass(){
    System.out.println("OuterClass consturctor");
   
  # 내부 클래스
  class InnerClass(){
    ㅑint num = 100;
     String str2 = str1;
  }
  
  # 내부 static 클래스
  static class SinnerClass(){
   int num = 1000;
   String str3 = str1;
   
   public SInnerClass(){
      System.out.println("static InnerClass constructor");
   }
  }
}
// main 함수
public static void main(String[] args){
  # 외부 클래스 객체 oc 할당
  OuterClass oc = new OuterClass();
 
  // 내부 클래스 InnerClass 객체 in 할당 
  OuterClass.InnerClass in = oc.new InnerClass();  //  oc 객체로 
  // InnerClass 타입의 객체 생성
  System.out.println("in.num : " + in.num); // 100
  
  // 내부 클래스 SInnerClass 객체 si 할당
  OuterClass.SInnerClass si = new OuterClass.SInnerClass();
  System.out.println("si.num =" + si.num); // 1000
  
  System.out.println();

익명(Ananymous) 클래스

이름이 없는 클래스 . 주로 메소드를 재정의하는 목적으로 사용된다.

  • 별다른 객체 선언없이 바로 클래스를 이름없이 정의한다.
  • 한번 쓰고 버리는 클래스
  • 이름이 없기 때문에 이 클래스로 객체를 호출할 수 있는 방법은 없다.

형식
부모클래스 변수명 = new 부모클래스(매개값, ... ) {
---- 메소드 정의 내용 ----
};

익명 자식 객체를 생성하는 3가지 방법

    1. 필드의 초기값
    1. 로컬변수의 초기값
    1. 매개변수의 매개값

예제

이런 평범한 클래스가 있다고 할때,

package Anonymous;

public class Insect {

	void attack(){
		System.out.println("곤충은 공격을 한다");
	}
}

우선 곤충 Insect 이라는 부모클래스를 정의했다.

향후 Insect 부모 클래스는 일시적으로 정의된 익명객체를 담아둘 변수로 사용되기도 하고, 익명객체가 무엇을 재정의해야할지 어느정도 컨셉을 잡아주는 역할로 사용된다. (상속개념)

package Anonymous;

public class Anonymous {

	//★★방법 1 : 필드에 익명자식 객체를 생성 
	Insect spider1 = new Insect(){
		
		String name = "무당거미";
		//거미줄을 치다.
		void cobweb(){
			System.out.println("사각형으로 거미줄을 친다.");
		}
		
		@Override
		void attack() {
			System.out.println(name + " 독을 발사한다.");
		}
	};
	
	//★★방법2 : 로컬변수의 초기값으로 대입
	void method1(){
		Insect spider2 = new Insect(){
			
			String name = "늑대거미";
			//거미줄을 치다.
			void cobweb(){
				System.out.println("육각형으로 거미줄을 친다.");
			}
			
			@Override
			void attack() {
				System.out.println(name + " 앞니로 문다.");
			}
		};
		
		//로컬변수이기 때문에 메서드에서 바로 사용
		spider2.attack();
	}
	
	//★★방법3 : 익명객체 매개변수로 대입
	void method2(Insect spider){
		spider.attack();
	}
	
	
}

그다음, 부모(곤충)객체 필드에 자식 익명객체를 바로 정의하여 초기값을 할당하고 있습니다.

또, method1을 보시면 해당 메서드 내부에서 지역적으로 익명객체를 생성하고, 바로 spider2.attack() 메서드를 호출하여 익명객체를 사용했습니다.

마지막으로 부모(곤충)객체를 매개변수 인자로 받게끔 하고, 받은 후 바로 spider.attack() 메서드를 호출하여 사용하도록 했습니다. 이제 위에서 정의한 Anonymous 클래스를 아래 main 함수에서 호출하도록 하면 아래와 같이 결과값이 나옵니다.

public class AnonymousExample {

	public static void main(String[] args) {
		
		Anonymous a = new Anonymous();
		
		//방법 1 : 익명객체 필드 사용
		a.spider1.attack();

		//방법2 : 익명객체 로컬 변수 사용
		a.method1();
		
		//방법3 : 매개변수로 익명개체 사용
		a.method2(new Insect(){
			String name = "타란툴라";
			
			//거미줄을 치다.
			void cobweb(){
				System.out.println("그냥 마구잡이로 친다.");
			}
			
			@Override
			void attack() {
				System.out.println(name + " 공격 안하고 후퇴한다..");
			};
		});
		
		//익명객체 내부에서 새롭게 정의된 필드,메서드는 부모객체로 생성된 spider1에서 접근할 수 없음!!!
		a.spider1.name = "왕거미"; //익명객체에서 새롭게 정의된 필드 (접근불가)
		a.spider1.cobweb(); //익명객체에서 새롭게 정의된 메서드 (접근불가)
		a.spider1.attack(); //부모클래스 Insect에서 오버라이딩해서 재정의한 메서드 (접근가능)
	}

}
profile
블로그 이전했습니다 🙂 : https://haon.blog

0개의 댓글