(Day 33) 중첩클래스
23년의 마지막 금요일이다. 23년이 이제 진짜 가는구나.
복습
인터페이스를 이용한 객체 사용 규칙 정의
인터페이스 활용시 이점
교체가 쉬워진다! 이 인터페이스를 (구현한 클래스로 만든 인스턴스(객체)) 쓴다고 코드를 작성하면, 나중에 그 부분을 교체하지 않고 한 두줄의 코드만 변경하여 다형성을 구현할 수 있다.
인터페이스와 추상클래스를 결합해서 사용하는 방법과 이유?
스택에 대해 설명과 사용예시
링크드 리스트를 상속받아 구현 가능 (반드시 링크드 리스트로 구현해야 하는 것은 아니지만) 푸시와 팝을 통해 넣고 peek으로 슬쩍 보는 (최상단 노드 확인) 나중에 넣은 걸 먼저 꺼내야 할 때 히스토리나 브레드크럼을 관리하는데 사용됨 메뉴 구조를 관리할 때 사용되니, 컴포지트 패턴과 함께 적용하기 좋은 자료구조다.
큐에 대한 설명과 사용예시
마찬가지로 링크드 리스트 상속받아 구현하면 구현이 편하다. 오퍼와 폴(poll) 메서드로 넣고 뺀다. 예약시스템 같이 먼저 들어온 요청을 먼저 처리해야 할 때 주로 사용된다.
이터레이터 패턴
인터페이스로 자료구조를 쉽게 바꿔서 쓸 수 있게 만든다고 했는데, 문제는 값을 꺼내는 방법이 동일하지 않은 경우가 있음 그래서 값을 꺼내는 방법을 동일하게 만들기 위해서 값을 꺼내는 역할을 하는 객체를 별도로 만들었음.
마찬가지로 이터레이터도 인터페이스를 먼저 만들고 제네릭 쓴 추상메서드로 hasNext(), next()
GPT
코딩을 하는 노가다성 작업은 GPT가 할 수 있다. 양산형 개발자 ㅋㅋ 지금의 나구만. 탈피해야해. 4천짜리 개발자 10명 -> 8천짜리 개발자 3명으로, 껍데기만 아는, 깊이가 얕은 사람들은 그들의 노가다성 작업이 없어질 것. 그러나 유행을 타지 않는 깊이가 깊은 기술을 아는 사람들은 반대로 연봉이 높아질 것임.
중첩클래스
Static Nested Class
Non-Static Nested Class (Inner Class)
이 경우 static nested class와 달리 this를 넘길 필요도 없고 외부 클래스의 어떤 객체 주소를 받아올 필요가 없어진다. 외부 클래스의 인스턴스 멤버에 접근가능해진다. 생성자에 자동으로 외부크랠스의 주소를 가져올 수 있게 컴파일러가 바이트코드를 생성한다.
위 이미지처럼 …
클래스의 구현
이터레이터 패턴의 구현 (꼭 이터레이터가 아니더라도..)
별도의 클래스로 작성하기
static 중첩 클래스 사용하기
Non-static 중첩 클래스 사용하기 (Inner class)
바깥 클래스의 인스턴스 주소를 받는 코드가 자동으로 추가된다.
Local Class 사용하기
특정 메서드 안에서만 사용되는 클래스라면, 그 메서드 안에서 클래스를 만들 수 있다.
Local Class 를 익명 클래스로 사용하기
=> 안드로이드에서 밥먹듯이(?) 쓰는 방법
Nested Class
1) static nested class => 바깥 클래스의 인스턴스에 종속되지 않는 클래스. => top level class 와 동일하게 사용한다.
2) non-static nested class = inner class => 바깥 클래스의 인스턴스에 종속되는 클래스. 중첩 클래스에서 바깥 클래스의 인스턴스 멤버를 사용한다는 뜻이다. 바깥 클래스의 인스턴스 없이 작업할 수 없는 경우 중첩 클래스를 non-static nested class 로 정의한다. => 바깥 클래스의 인스턴스 없이 생성할 수 없다.
3) local class => 특정 메서드 안에서만 사용되는 클래스. 특정 메서드 안에서만 쓰려는 목적이므로 다른 곳에서 접근할 public modifier를 사용하지 못하고 사용할 이유도 없음.
4) anonymous class => 클래스의 이름이 없다. 이름이 없으니, new 명령으로 따로 인스턴스를 생성할 수 없다. => 문법 = 클래스를 정의 하는 문법 + 인스턴스를 만드는 문법 즉, 클래스를 정의하는 동시에 인스턴스를 생성해야 한다. => 클래스 이름이 없기 때문에 익명 클래스는 생성자를 정의할 수 없다. 만약 인스턴스의 값을 초기화시키기 위해 복잡한 코드를 작성해야 한다면, “인스턴스 블록”을 사용하여 인스턴스 초기화 코드를 작성하라! => 단 한 개의 인스턴스만 생성해서 사용할 경우 익명 클래스를 적용한다. => 문법: new 수퍼클래스() {수퍼 클래스를 상속 받은 익명 클래스 정의} new 인터페이스() {인터페이스를 구현한 익명 클래스 정의} => 주의! new extends 수퍼클래스 implements 인터페이스 {익명 클래스 정의} <== 이런 문법은 없다.
new 수퍼클래스 implements 인터페이스() {인터페이스를 구현한 익명 클래스 정의} <== 이런 문법은 없다.
new 인터페이스1, 인터페이스2, 인터페이스3() {인터페이스를 구현한 익명 클래스 정의} <== 이런 문법은 없다.
수퍼 클래스를 지정하거나 인터페이스를 지정하거나 둘 중 하나만 해야 한다.
중첩클래스도 클래스의 멤버이기 때문에 필드나 메서드처럼 접근 제한자를 붙일 수 있다.
스태틱 중첩 클래스는 상속하고 조금은 유사한 것 같다. 스태틱에서 멤버(메서드와 필드)가 없으면 아우터 클래스의 스태틱 멤버에 그것이 있는지 찾는다. 스태틱 클래스는 아우터클래스의 주소를 가지고 있지는 않으므로 this 사용은 불가하다. 아우터클래스의 인스턴스 멤버에 접근할 수 없다.
네스티드 스태틱 클래스는 사용 가능하다. 인스턴스 멤버는 스태틱 멤버를 사용할 수 있다.
import 가 됩니다.
// 스태틱 멤버를 임포트하기
import static com.eomcs.oop.ex11.b.E.m1;
import static com.eomcs.oop.ex11.b.E.v1;
import static com.eomcs.oop.ex11.b.sub.M.m2;
import static com.eomcs.oop.ex11.b.sub.M.v2;
// 중첩 클래스를 import 할 때는 static을 적지 않는다.
import com.eomcs.oop.ex11.b.E.X;
import com.eomcs.oop.ex11.b.sub.M.Y;
중첩 클래스
중첩클래스가 있다 논스태틱 클래스다. 그러면 이너클래스라고도 부른다.
이너클래스가 있다. 이너클래스를 만드는 문장은 낯설다. 이너클래스를 만드려면 아우터클래스 인스턴스 주소로부터 만들어야 한다. 아우터클래스 이름으로는 안된다는 것이다. 그건 스태틱 중첩 클래스에서 가능하다. 그래서 코드가 낯설게 나온다.
아우터클래스명 아우터인스턴스명 = new 아우터클래스생성자
아우터클래스명 이너인스턴스명 = 아우터인스턴스명.new 이너클래스생성자
이렇게 아우터인스턴스명.new 이너클래스생성자
라는 생소한 형태를 보게 된다. 그리고 이너인스턴스명
이라는 레퍼런스 변수에는 this$0
라는 아우터클래스의 주소를 담고 있다.