ultra_dev
이것이 자바다 CH 9(중첩 선언과 익명 객체) 본문
CH9
☑️ 중첩 클래스
: 클래스 내부에선언한 클래스
→ 외부에 중첩 관계 클래스를 감춤으로써 코드의 복잡성 줄일 수 있음
- 클래스가 특정 클래스랑만 관계를 맺을 경우 편의성 때문에 중첩 클래스로 선언해서 사용하는 경우 많음
📌**멤버 클래스 : 클래스의 멤버로서 선언 되는 중첩 클래스**
- 인스턴스 멤버 클래스
class A {
class B {...}
}
-> A객체를 생성해야만 B객체 생성 가능
- 정적 멤버 클래스
class A {
static class B{...}
}
-> A 객체를 생성하지 않아도 B객체를 생성 가능
📌**로컬클래스 : 메소드 내부에서 선언되는 중첩 클래스**
class A {
void method() {
class B {...}
}
}
-> 메소드 실행할 때만 B 객체 생성 가능
☑️ 중첩 클래스도 클래스이므로 컴파일시 .class 바이트코드 파일 생성
바깥클래스 $ 멤버클래스.class
바깥클래스 $1 로컬클래스.class
☑️인스턴스 멤버 클래스
[public] class A{
[public | private] class B{}
}
A클래스의 멤버로 선언되 B클래스 같은 경우를 말함
- public class B{} : 다른 패키지에서 B클래스 사용 가능
- class B {} : 같은 패키지에서만 B 클래스 사용 가능
- private class B {} : A 클래스 내부에서만 B클래스 사용 가능
→ 이 경우 주로 A클래스 내부에서 사용되므로 private 접근제한을 갖는 것이 일반적
→ B클래스는 A 클래스 내부 인스턴스 필드값, 생성자, 메소드에서 생성 가능..
어디서나 생성 가능한 것이 아님
why? A객체가 있어야 B객체도 생성할 수 있기 때문
public class A{
class B{}
//필드값에 B 객체 대입
B field = new B();
//생성자
A() {
B b = new B();
}
//메소드
void method() {
B b = new B();
}
}
📌 만약 B객체를 A클래스 외부에서 생성하려면 public,default 접근 제한을 가져야 하고
A객체 먼저 생성 후 B객체 생성
A a = new A();
A.B b = a.new B();
- 인스턴스 멤버 클래스 B 내부에는 당연히 일반 클래스처럼 필드, 생성자, 메소드 선언 가능
but 정적필드와 정적메소드는 JAVA 17부터 선언 가능!
☑️ 정적 멤버 클래스
:static 키워드와 함께 A클래스의 멤버로 선언된 B 클래스
[public] class A {
[public|private] static class B {}
}
- publiac static class B {} : 다른 패키지에서 B클래스 사용 가능
- static class B {} : 같은 패키지에서만 B클래스 사용 가능
- private static class B {} : A 클래스 내부에서만 B 클래스 사용 가능
→ 정적 멤버 클래스 B는 A클래스 외부에서 사용하는 경우 많기 때문에 주로 default,public 접근 제한 가짐
- A클래스 외부에서 B 객체 생성하려면 A 객체 생성 없이 A클래스로 접근해서 B 객체 생성 가능
A.B b = new A.B(); <ㅡ a객체 생성 필요없음
☑️ 로컬 클래스
: 생성자 또는 메소드 내부에서 다음과 같이 선언된 클래스
class A{
//생성자
public A(){
class B {}
}
//메소드
public void method(){
class B{}
}
}
→ 로컬 클래스는 생성자와 메소드가 실행될 동안에만 객체 생성 가능
→ 로컬 클래스 B 내부에는 일반 클래스처럼 필드,생성자,메소드 선언 올 수 있음
정적필드, 정적 메소드는 Java17부터 선언 가능
📌 로컬 변수(생성자 또는 메소드의 매개변수 또는 내부에서 선언된 변수)를 로컬 클래스에서 사용할 경우 로컬 변수는 final 특성을 갖게 되므로 값을 읽을 수만 있고 수정 불가
→ 로컬 클래스 내부에서 값을 변경하지 못하도록 제한
→ Java8 이후부터는 명시적으로 final 키워드 붙히지 않아도 되지만, 로컬 변수에 final 키워드 추가해서 명확히 하는 것도 좋음
public class A {
public void method1(int arg) {
//로컬 변수
int var = 1;
//로컬 클래스
class B {
void method2() {
System.out.println(arg);
System.out.println(var);
//로컬 변수 수정 -> 불가능
arg = 2; -> 불가능
var = 2; -> 불가능
}
}
//로컬 객체
B b = new B();
//로컬 객체 메소드 호출
b.method2();
//로컬변수 수정 -> 불가능
arg=3; -> 불가능
var=3; -> 불가
}
}
☑️ 바깥 멤버 접근
:중첩 클래스는 바깥 클래스 멤버(필드,메소드)에 접근 가능
- 인스턴스 멤버 클래스 : 바깥 클래스의 모든 필드와 메소드 사용 가능
- 정적 멤버 클래스 : 바깥 클래스의 정적 필드와 정적 메소드 사용 가능
→ 정적 멤버 클래스는 바깥 객체가 없어도 사용 가능해야 하니 바깥 클래스의 인스턴스 필드와 인스턴스 메소드는 사용 불가
☑️바깥 클래스의 객체 접근
:중첩 클래스 내부에서 this는 해당 중첩 클래스 객체 의미하므로,
중첩 클래스 내부에서 바깥 클래스 객체 얻으려면 밑에처럼 해줘야 함
바깥클래스이름.this -> 바깥 객체 의미
public class A {
String field = "A";
void method(){..."A"}
class B {
String field = "B";
void method(){..."B"}
void abmethod(){
System.out.println(this.field);//B클래스 필드
this.method(); //B클래스의 메소드
System.out.println(A.this.field);//A클래스 필드
A.this.method(); // A클래스의 메소드
☑️ 중첩인터페이스
:클래스의 멤버로 선언된 인터페이스
→ 해당 클래스와 긴밀한 관계를 맺는 구현 객체 만들기 위해 사용
class A {
[public|private] [static] interface B {
//상수필드
//추상 메소드
//디폴트 메소드
//정적 메드
}
→ 외부의 접근 허용하려면 public, A클래스 내부에서만 사용할거면 private, 아무것도 안붙히면 같은 패키지 안에서만 접근 가능
→ 중첩 인터페이스는 안드로이드와 같은 UI 프로그램에서 이벤트 처리 목적으로 많이 활용됨
ex) 버튼 클릭했을 때 이벤트를 처리할 객체는 중첩인터페이스를 구현해서 만듦
☑️ 익명 객체 -> 보통 재사용 안할 경우 사용? 따로 빼서 인터페이스나 클래스하기도 낭비라고 생각되는?
: 이름이 없는 객체
- 명시적으로 클래스를 선언하지 않아서 객체 쉽게 생성 가능
- 익명 객체는 필드값, 로컬 변수값, 매개변수값으로 주로 사용됨
- 클래스를 상속하거나 인터페이스를구현해야만 생성 가능
- 클래스 상속시 → 익명 자식 객체
- 인터페이스 구현시 → 익명 구현 객체
☑️ 익명 자식 객체
: 부모 클래스를 상속 받아 생성
new 부모생성자(매개값,...) {
//필드
//메소드
}
→ 중괄호 블록 안의 필드와 메소드는 익명 자식 객체가 가져야 할 멤버로, 중괄호 블록 안에서만 사용 가능
→ 주로 부모 메소드를 재정의 하는 코드가 들어감
📌 필드에 익명 자식 객체 대입 하는 경우
//필드에 익명 자식객체 대입
private Tire tire2 = new Tire() {
@override
public void roll() {
System.out.println("익명자식객체입니다")
}
}
이런식으로 new 부모생성자()하고 바로 중괄호 {}
📌로컬 변수에 익명 자식 객체 대입
public void run2() {
//로컬변수에 익명자식객체 대입
Tire tire = new Tire() {
@Override
public void roll() {
System.out.println("익명자식객체입니다")
}
}
tire.roll();
}
☑️ 익명 구현 객체
:인터페이스를 구현해서 생성
new 인터페이스() {
//필드
//메소드
}
→ 중괄호 블록 안의 필드와 메소드는 익명 구현 객체가 가져야 할 멤버로, 중괄호 블록 안에서만 사용 가능
→ 주로 인터페이스의 추상 메소드를 재정의 하는 코드가 들어감
📌 위의 익명 자식 객체와 유사하다
'이것이 자바다' 카테고리의 다른 글
이것이 자바다 CH12.모듈 (0) | 2023.01.27 |
---|---|
이것이 자바다 CH 11(예외처리) (0) | 2023.01.13 |
이것이 자바다 CH 8(인터페이스) (0) | 2023.01.13 |
이것이 자바다 CH 7-2(상속) (0) | 2023.01.13 |
이것이 자바다 CH 7-1(상속) (0) | 2023.01.13 |