중첩클래스와 중첩인터페이스

Java

목록 보기
12/26
post-thumbnail

1. 중첩클래스


멤버 클래스 : 인스턴스 멤버 클래스 / 정적 멤버 클래스
로컬 클래스 : 메소드 안에서 동작하는 클래스(static 붙일 수 X)

  • 장점 : 내부 클래스에서 외부 클래스에 쉽게 접근 가능(inner클래스는 객체 생성 없이 outter 클래스에 접근 가능)

1-1. 인스턴스 멤버 클래스

  • A클래스의 객체 생성 → B클래스 객체 생성 후 사용 가능
  • 정적 메소드 ❌
  • 정적 필드 ❌
A a = new A();
A.B b = a.new B();
b.field1 = 3;
b.method1();

일단 B클래스의 객체를 만들고 나면
b.method 이렇게 접근 가능! but 정적 멤버 클래스는
A.C.method 이렇게 접근함. 밑에 나옴.

public class A {
	
	A() {
		System.out.println("A객체가 생성됨");
        B b = new B();
	}
}
	class B {
		int field1;
        static int field2;						>>staticB(){   
		System.out.println("B객체가 생성됨");
	}
		void method1() {   }
		static void method2() {   } 			 >>static}

C클래스

public class C {

	public static void main(String[] args) {
		A a = new A();
		A.B b = new B(); 		>>B객체를 먼저 만들어야함
		B b = a.new B();
        b.field1 = 3;
        b.nethod();
	}
}

1-2. 정적 멤버 클래스

  • 정적 필드⭕ 정적 메소드 가능 ⭕
A.C c = new A.C();
c.field1 = 3;
c.method1();
A.C.field2 = 3;
A.C.method2();

C.method(); 이렇게 못함!! ✅인스턴스 멤버 클래스와 메소드/필드 호출 방법이 다름

1-3. 로컬 클래스

  • 메소드 안에 있는 클래스이기 때문에 바깥 클래스의 객체 생성 안 해도 됨.
    A.D도 안 찍어도 됨.
  • static (정적 ~~) 선언 불가
D d = new D();
d.field1 = 3;

1-4. 중첩 클래스의 접근 제한

public class A {
	
	class B { }
	static class C { }

	//인스턴스 필드
	B field1 = new B(); 		//B타입의 필드
	C field2 = new C();			//C타입의 필드
	
	//인스턴스 메소드
	void method1() {
		B var1 = new B(); 
		C var2 = new C();
	}
	
	//정적 필드
	//static B field3 = new B();			//static이기 때문에 A객체 없이도 B클래스가 사용되어야 함. 
											//하지만 B 클래스는 A객체 없이는 호출될 수 없음.
	static C field4 = new C();
	
	
	//정적 메소드
	static void method2() {
		B var1 = new B();					//같은 이유
		
	}	
}

인스턴스 필드인스턴스 메소드는 인스턴스 멤버 클래스든 정적 멤버 클래스든 다 사용할 수 있는 반면
정적 필드정적 메소드는 정적 멤버 클래스만 사용할 수 있다.

  • 뭔 말? : (by자바의정석) 내부클래스가 static iv를 가질 경우는 static (내부) 클래스일 경우만 가능하다. ▼ (상수(final static) 경우는 제외)

    instance → static 접근은 가능. 그 반대는 불가.

    왜 C 안에 field1을 못 넣는가? 외부에서 C의 field1을 사용하려면 A의 객체를 만들어야하는데, A안에서 field1은 A객체를 만들어야 사용가능하기 때문. 메소드도 마찬가지.

1-5. 로컬 클래스에서 사용 제한

public void method2(int arg) {
int localVariable = 1;
arg = 100;❌
localVariable = 100;class Innter {
	public void method() {
    	inr result = arg + localVariable;
    }
    }
}

arg와 localVariable는 final을 안 붙여도 final 특성을 가짐.
method1 실행 후 끝나면, 저 변수들이 사라지게 됨. 그런데 아직 내부에있는 Inner 클래스는 돌아가고 있다면, 그 값들이 사라져서 작동할 거리가 없어짐. 그러니까 없어지면 안되므로 final로 붙박아놓음.

1-6. 중첩 클래스에서 바깥 클래스 참조 얻기

2.중첩 인터페이스

  • 인터페이스 안에 인터페이스❌
  • 클래스 안에 인터페이스⭕
class A {
	interface I {
    		void method();
        }
  }

구현 (이거 ㅈㄴ복잡함)

public class Button {

	OnClickListener listener;
	
	void setOnClickListener(OnClickListener listener) {
		this.listener = listener;
	}
	
	public void touch() {
		 listener.onClick();
	}
	
	interface OnClickListener {
		void onClick();
	}	
}
public class CallListener implements Button.OnClickListener{

	@Override
	public void onClick() {
		System.out.println("전화를 합니다");	
	}
}
public class MessageListener implements Button.OnClickListener{

	@Override
	public void onClick() {
		System.out.println("메세지를 보냅니다");		
	}
}	
public class BottonExample {

	public static void main(String[] args) {
		Button btn = new Button();
		
		btn.setOnClickListener(new CallListener());
		
		btn.touch();
		
		btn.setOnClickListener(new MessageListener());
		btn.touch();
        
        	//익명구현객체 방법   : 이걸 많이 써요(by.이자바)
		btn.setOnClickListener(new Button.OnClickListener() {
			
			public void onClick() {
				System.out.println("사진을 찍습니다");
			
		}
	});
				btn.touch();
	}
}

2-1. 익명 객체

  • 익명 객체는 단독으로 생성할 수 없다.
    - 클래스를 상속하거나 인터페이스를 구현해야만 생성할 수 있다.
  • 익명 자식 객체 생성
부모 클래스 [필드|변수] = new 부모클래스(매개값) {
//필드
//메소드
}
class A {
Parent field = new Parent() {
	int childField;
    coid childMethod() {  }
    @Override
    void parentMethod() {  }
};
}
  • 메소드의 매개값으로 익명 객체 생성
void method1(Parent parent) { }
void method2() {
method1(
new Parent() {
	int childField;
    coid childMethod() {  }
    @Override
    void parentMethod() {  }
}
);
}


▲ 이건 진짜 개쌉 모르겠음.
영상 보면 이해는 감.
영상 다시 보기

  • 익명 구현 객체 생성(인터페이스)
인터페이스 [필드|변수] = new 인터페이스() {
//인터페이스에 선언된 추상 메소드의 실체 메소드 선언
//필드
//메소드
};

0개의 댓글