추상적
어떤 일을 해야할지 결정x, 정해지지않은
공통적인
구체적
어떤 일을 해야할지 명확하게 정의
구성 요소 중에서 정해지지 않은 클래스
public abstract class 클래스명 {
public abstract int add(int num1, num2);
혹은
abstract public int add(int num1, num2);
}
본인이 만들진 않지만 하위클래스가 따라야 할 원칙을 정의해서 반드시 원칙을 구현 할 수 있게
추상메서드를 통해 정의
왜 이런 원칙을 정하지?
-> 엘지랑 삼성에서 모니터 만들 때 표준 규격을 지키지 않으면 매출의 큰 타격을 받겠지??
-> 표준 규격을 지키자ㅏ
-> 안따르면 오류가 떠서 따를 수 밖에 없음
-> 오류 : 통제수단, 개발자가 반드시 따라야 할 부분 통제
int num;)int num = 10;)참고)
위 두가지 역할 중 하나만 해도 ㅇㅋ
-> 예시3, 4번 참조
예시)

ㄴ 추상클래스 정의(Calculator)
ㄴ {}가 없다
= 구현내용이 없다
= 함수는 기능이 가장 중요한데 기능을 할 수 없음
= 불완전한 클래스
ㄴ 음? 구현내용이 없으면 객체가 될 수 없는데 객체가 안되면 사용할 수 없어서 의미가 없지 않나(= 클래스를 정의한 의미가 없지 않나)
ㄴ 상속을 통해서 객체를 만들어 사용가능

ㄴ 하위 클래스(SimpleCalculator) 생성함

ㄴ 객체생성을 위한 클래스 정의(Ex01)
ㄴ 클래스가 완전해야지만 객체를 생성 할 수 있는데 구현내용이 없으니 불완전한 클래스라 객체를 만들 수 없음
ㄴ 하위클래스를 통해 객체 생성하자

ㄴ 오류 해결
ㄴ 음? 근데 하위클래스 아직도 에러 떠 있음

ㄴ 왜 에러가 뜨지?
ㄴ add(10,20); 을 뭘 할지 하위클래스도 구현내용을 명시 안했으니까
ㄴ 메서드 재정의(오버라이드)를 해줘야 함

ㄴ 구현내용을 넣어주자ㅏ

ㄴ 구현내용을 넣어줌(완벽한 클래스가 되었다)으로서 오류해결

ㄴ 구현내용 바꿈

ㄴ 객체가 되었다
예시2) 추상클래스에 멤버변수(num) 정의


ㄴ cal.num : 추상클래스(Calculator)에 정의된 num을 의미
ㄴ 이상하다 추상클래스는 불완전한 클래스라서 객체가 될 수 없는데 num이 변수가 되어 값이 출력이 됬네??
ㄴ 객체가 되었다는 소리
ㄴ 추상클래스 (Calculator)로 부터 하위 클래스(SimpleCalculator) 가 상속받아서 메서드 재정의 실현함
ㄴ 객체가 되지 않으면 상속이 되지 않음
ㄴ 메서드재정의 : 인스턴스메서드만 가능 -> 인스턴스메서드도 객체가 되어야지만 가능
ㄴ 재정의는 객체가 되야하고 상속도 되야지 재정의가 가능
ㄴ 즉, 재정의가 되었다는 것은 객체가 되었다는 말
ㄴ 추상클래스는 불완전하니까 직접생성하는 것을 막은 것
ㄴ 하지만 내부적으론 객체가 되어있다

ㄴ 다형성!! (하위클래스 -> 상위클래스)

ㄴ SimpleCalculator cal = new SimpleCalculator(); -> Calculator cal = new SimpleCalculator(); 가능 (다형성)
예시3) 추상클래스(Calculator)에 기본생성자 정의
추상클래스는 외부적으론 객체가 될 수 없지만, 내부적으론 객체가 되어있다


ㄴ 따로 호출하지 않아도 기본생성자에 정의한 내용(Calculator 생성자!)이 출력됨

예시4) 하위클래스가 공유해야 할 공통적인 자원 정의 가능
추상클래스에 추상메서드가 필수이냐?
그건 또 아님 정의 하지 않는 경우도 있음
-> 추상클래스의 역할 2가지 중 하나만 해도 ㅇㅋ

: 상수( = 변경 불가)
: 재정의 불가( = 변경 불가)
ㄴ 메서드 변경 불가 = 재정의 불가
예시)

벗 메서드 재정의 하면 하위클래스가 순서를 바꿀 수 있으므로 재정의 못하게 final처리하기


ㄴ 재정의 못하게 오류 뜸
: 상속 불가( = 변경 불가)
예시)


참고)
API(Application Programming Interface) : 개발 시 필요한 설계 가이드 라인
JDBC API(Java DataBase Connectivity Application Programming Interface)
interface 인터페이스명 {
추상메서드 정의..
}
설계만을 위한 클래스이기 때문에 모든 메서드를 추상메서드로 판단함
-> 구현체 있으면 오히려 이상하다고에러 표시함
보이지 않지만 자동으로 public abstract를 추가해 줌(생략해서 써도 ㅇㅋㅇㅋ)
-> 무족건 추상메서드만 정의하니까
-> 벗 추상클래스는 설계 및 공통자원 두가지 역할을 하기 때문에 추상메서드일수도 있고 공통자원메서드 일 수도 있어서 형식을 다 갖춰야함_ public abstract 생략 불가

예시)


ㄴ 오류 해결 완
class 클래스명 implements 인터페이스1, 인터페이스2,...{
}
인터페이스는 쪼개서 설계가능
-> 설계의 유연성↑
-> class 클래스명 implements 인터페이스1, 인터페이스2...{}
임플리먼트 메서드도 오버라이드 메서드와 동일한 기능(= 재정의)이라 봐도 ㅇㅋ
-> 벗 오버라이드는 해도되고 안해도 되는거지만 임플리먼트 메서드는 무족건 해야 함
예시) 다형성


예시)
주문 - 판매자 구매자
-> 인터페이스1: 판매자 , 인터페이스2 : 구매자
-> 주문쪽에서 구현하는 방식으로 설계

ㄴ 주문쪽에서 구현하는 방식으로 설계

ㄴ Order객체 생성



ㄴ Order가 Buyer도 될 수 있고 Seller도 될 수 있다(다형성)

ㄴ 다형성
참고) 인터페이스 gerate로 빠르게 구현가능 (컨트롤 + I)
인터페이스 클래스에서 변수 정의 ≠ 멤버변수
-> 객체를 만들기 위한 클래스가 아니라 설계만을 목적으로 하기 때문에 멤버변수 선언 못함
-> 추상클래스 : 외부적으론 객체생성 못함 내부적으로만 객체생성 가능
-> 객체의 자원정의 못함 ex) 멤버변수...
-> 멤버변수 : 객체가 되어야지만 사용 가능함
인터페이스 클래스에서 변수 정의 = 정적상수
-> 변수선언만 해도 앞에 public static final 이 자동 추가 됨
예시)

ㄴ int num; : 초기값을 넣어주라고 에러가 뜸

ㄴ int num = 10;은 멤버변수가 아니다
ㄴ 멤버변수는 바로 초기화를 하지 않고 객체 생성하고 나서 초기화해도 되는데 위 인터페이스 클래스는 그렇게 못하게 에러 뜸
-> 인터페이스는 객체를 만들 목적이 아니기 때문
ㄴ 그럼 int num = 10; 은 뭐지?
-> Static이다!
-> 변수를 정의한다는 것은 쓸려고 정의한 것이다
-> 인터페이스는 추상메서드이기 때문에 객체생성 못함 (내부적으론 객체이겠지만 외부적으론 객체가 아니다)
-> 객체를 만들지 않고도 쓸 수 있어야 하기 때문에 Static!

ㄴ 객체를 만들지 않았음에도 접근가능하다ㅏ

ㄴ 초기화한 값 변경하려니 에러 뜸 -> 정적상수이다

ㄴ 정적상수이기 때문에 인터페이스 클래스에서 변수 정의 시 public static final 이 자동 추가 되어있음

-> Adapter 클래스를 통해 내가 필요한 추상메드만 구현 가능하게 개선함
-> 벗 상속은 단일상속만 가능, 다중상속이 안됨
-> 유연성이 떨어짐
-> 개발자들이 항의함
-> 인터페이스의 목적(설계)에는 맞지 않지만 인터페이스에서도 완전히 구현된 인스턴스메서드 정의할 수 있게 함(자바7에서 추가)
-> 그게바로 default 메서드임
-> default 메서드 : 내가 필요한 추상메서드만 구현 가능하게 개선함 + Adapter 클래스보다 유연성이 높음(다중상속가능)
예시) default 메서드❓

ㄴ 인터페이스 클래스는 모두 추상메드라 인식해서 자동으로 public abstract를 추가함
ㄴ 완전히 구현된 메서드를 정의하니 오류 뜸(추상메서드는 불완전해야함)
ㄴ 일부러 정의한 완전히 구현된 메서드 임을 알려주자

ㄴ default를 넣어줌으로서 완전히 구현된 메서드를 일부러 정의한거라고 컴파일러에게 알려줌
ㄴ 오류 해결
ㄴ 접근범위는 무조건 public임



ㄴ 인터페이스 Buyer 클래스에서 완전히 구현된 order 메서드가 호출됨
예시1) 과거엔 Adapter 클래스

모든 하위클래스는 반드시 추상메서드를 구현해야함
-> 추상메서드 : 설계의 원칙

컬큐레이터 1번 과 2번에만 스퀘어가 필요하지만 3번 4번에 도 추가를 안하면 오류가 뜨기 때문에 3,4번에도 스퀘어를 추가해 줘야 함
-> 추상메서드는 설계의 틀 규제이기 때문에 이 설계를 따라줘야 함 그래야 완전한 클래스가 될 수 있음


기본구현된 Adapter 클래스를 통해 필요한 추상메서드만 재정의를 통해서 구현 할 수 있도록 함
-> 모든 추상메서드를 구현해야 한다는 단점 해결
예시2) Adapter 클래스

마우스리스너 인터페이스 : 총 5개의 추상메서드가 정의되어 있음
내가 마우스리스너의 기능을 쓰고 싶음
그러면 5개의 추상메서드를 모두 구현해야만 사용 가능함

ㄴ 마우스리스너라는 인터페이스의 5개 추상메서드를 구현하지 않았기 때문에 오류 뜬거임

아 근데 나는 마우스리스너라 인터페이스에서 마우스클릭 추상메서드 1개만 필요한데 다 구현해줘야 하네ㅠ
-> 코드도 많아지고 불편

ㄴ Adapter클래스 : 추상메서드 기본구현 다 해줌
-> 기능은 비어있지만 구현체가 다 들어가 있음
-> 완벽한 클래스가 되었다ㅏ

ㄴ Adapter클래스를 통해 기본구현 다 해놓고 내가 진짜 필요한 추상메서드는 Adapter클래스한테 상속받아서 메서드 재정의를 통해 구현하자

예시3) Adapter 클래스

ㄴ 인터페이스 정의

ㄴ implements 통해 어댑터클래스가 인터페이스에 있는 모든 추성메서드 기본구현함 -> 완전한 클래스 완성

ㄴ 필요한 기능만 상속을 통해 메서드 재정의

ㄴ 인터페이스에 기능 추가함
ㄴ 어댑터클래스에만 에러 뜨고(미구현된 추상메서드가 있으니까) 찐 구현내용 정의 할 클래스(Calculator2)에는 에러 안뜸(오버라이딩은 필수가 아닌 선택)

ㄴ 어댑터 클래스를 쓰기 전 : 모든 하위클래스에 추가된 추상메서드를 구현해야 함
ㄴ 어댑터 클래스 나온 후 : 어댑터 클래스에만 추가된 추상메서드 구현해주면 됨


{} 내에서만 가능
인터페이스는 추상 메서드이기 때문에 호출 주체는 명확(구현한 클래스의 메서드)
-> 인터페이스 : 다중 구현(상속)이 가능
클래스에서는 다중 상속 시 인스턴스 메서드가 동일하면 하위클래스가 호출 주체를 정하지x
-> 클래스 : 단일 클래스만 상속가능 , 다중 상속 불가
예시) 인터페이스
①
interface A
void method();
②
interface B
void method();
③
class C implements A, B
public void method(){...}

참고) 클래스의 상속은 한개만 가능(단일 상속)
1번과 2번 중 무얼 상속받아야 할지 애매해서 단일상속만 가능
super()를 통해 어떤 인터페이스에서 온건지 명시해주기예시)
Seller쪽에도 Buyer에서 정의한 거랑 동일한 default 메서드 order()를 추가 해 볼까?


ㄴ 1 related problem 문제가 발생했넹

ㄴ 인터페이스 Buyer 클래스, 인터페이스 Seller 클래스 중 어디서 온 order인지 헷갈려서 오류 뜸
ㄴ 즉 구현된 메서드가 동일할 때 어디서 온 메서드인지 애매함
ㄴ 추상클래스에서 단일상속밖에 안되는 이유였던 문제와 동일한 문제가 나타남

ㄴ 헷갈리는걸 없애주자 : Order클래스(하위클래스)에서 메서드 재정의하고 super를 통해 어느 인터페이스클래스에서 온건지(=Buyer) 명시해 주기

참고) 왜 인터페이스에서 implements 안쓰고 extends를 쓰나요?
-> 체계를 나누기 위해서 라고 함
컬렉션 프레임워크
(Collection Framework)
- Collection : 데이터 군집, 자료
- Framework : 표준적인 설계 틀
1) 자료구조
Collection 인터페이스
- List 인터페이스 : 순차자료구조
- Set 인터페이스 : 집합자료구조
- Map 인터페이스 : 사전자료구조
예시)




ㄴ 어? X 인터페이스랑 Y인터페이스에 동일한 method()가 있네??
ㄴ 문제가 안됨
ㄴ 왜?
ㄴ 인터페이스는 추상메서드가 주 목적
ㄴ 실제 이 메서드가 구현된게 아님
ㄴ 하위클래스 = 구현한 클래스에서 정의하고 그게 호출되는 것이기 때문에 호출주체가 명확하다
-> 그래서 다중상속해도 문제가 없다

ㄴ 문제 : method() 는 어디서 온 메서드 일까?
ㄴ 모르겠으니 확인해 보자

ㄴ 중복된 메서드method()가 X,Y,Ex01에 정의되어 있다 하더라도 실제 이 메서드의 주인은 구현체가 있는 Ex01이다

결론 :
인터페이스는 설계만을 목적으로 하기 때문에 추상메서드로 구성되어있음(default메서드 제외)
-> 중복된 메서드가 있어도 호출되는 주체는 중복된 메서드를 구현한 클래스(하위클래스)이다
-> 구현체 = {}
-> 그래서 인터페이스는 출처가 명확하기 때문에 다중상속을 해도 애매하지 않아서 다중상속이 가능함(↔ 추상클래스는 애매해서 단일상속만 가능)
찐한줄결론 :
중복된 메서드를 호출할 때 호출되는 것은 구현한 클래스의 메서드이다.
int num;)-> 목적이 더 많다
-> 다중 상속X -> 설계의 유연성 ↓
-> 인터페이스로 설계 많이 함(분리가능, 다중구현가능 하기 때문에)
int NUM = 10;)참고)
-> 내부클래스는 static을 정의하지 못함
-> 내부클래스는 외부클래스가 객체가 되어야만 접근이 가능한데 static은 객체생성유무 상관없이
항상 접근 가능해야 하니까
-> 근데 자바 16버전부터는 내부클래스에 static정의 가능하도록 바뀜
참고)
인스턴스 = 객체의 자원이다
객체와 관련이 있다
↔ static = 객체와 관련없다
예시)

ㄴ 내부 클래스에 함수정의

ㄴ 외부 클래스 객체 생성 이후에야 내부클래스 객체 생성 및 접근 가능
예시)


ㄴ 내부클래스(Inner)에서 외부클래스(Outer)의 인스턴스 자원(num1) 접근 가능
ㄴ 어떻게? 같은 인스턴스 자원으로서
ㄴ 내부클래스도 외부클래스(Outer)의 인스턴스 자원이다
ㄴ 즉 num1, Inner 모두 Outer의 인스턴스 자원이다
예시)

ㄴ Outer, Inner함수에 동일한 num1변수가 있다 어떤걸 따를까?
-> Inner함수꺼를 따른다ㅏ
예시)

ㄴ 음? 나는 외부클래스의 num1을 쓰고 싶어
-> Outer.this : Outer , 외부클래스에 있는 인스턴스 자원을 접근 할 때 사용
-> this : Inner
참고)
- this없음 : 객체 생성과 상관이 없다보니 객체의 주소를 참고하는 this없음
= 객체의 자원 접근 못함
= 멤버변수, 인스턴스 메서드 호출 불가 -> 왜? -> this가 없으니까
- super도 없음
예시)


ㄴ 외부클래스 객체생성이 안되어 있어도 내부클래스 객체 생성 가능
예시) 정적인 자원은 객체 생성과 관련이 없기 때문에 인스턴스 자원 접근 안됨
(반대로 인스턴스 자원은 정적인 자원 접근 가능)

ㄴ 아우터 클레스의 인스턴스 자원 num1접근 불가
ㄴ 정적 자원 -> 인스턴스자원 접근x

ㄴ 아우터 클래스의 정적자원 num2는 접근 가능
ㄴ 정적자원 -> 정적자원 접근ㅇㅋ
예시) 이렇게는 많이 안쓴다!

ㄴ 함수 안에 내부클래스(Inner)정의
ㄴ Inner inner = new Inner(); 내부클래스 객체 생성
-> Outer를 호출했을 때 메서드 내부에서 Inner클래스가 정의되고 객체가 생성되고 실행된다
-> 즉 지역내부(함수 내부)에서도 클래스(내부클래스) 정의가 가능하네
-> 다만 내부클래스는 method()함수가 호출되어야지만 존재하는 것

ㄴ outer.method(); : 함수 호출 -> 내부클래스 정의 -> 클래스가 객체가 됨
ㄴ 지역내부에서도 이런식으로 객체를 생성 할 수 있다
예시)

ㄴ 인터페이스 클래스 생성

ㄴ 지역내부 = 함수내부
ㄴ method(){ ①지역내부 }

ㄴ ① 조건만 충족
ㄴ 에러 뜬 이유 : ② 조건 아직 충족 못해서 객체생성 못하니까 에러 뜸

ㄴ ② 조건 충족
ㄴ Calculator라는 인터페이스가 객체가 됨
method(){
Calculator cal = new Calculator(){
② 미구현된 메서드 구현
};
}

ㄴ 호출되는지 함 볼까

ㄴ 오 되네 = 객체가 진짜 됬넹 = 인터페이스도 객체가 될 수 있다
-> 근데 이거 용도가 10과 20을 더하는 용도 밖에 안되넹 = 1번 밖에 못쓴다
-> 활용도가 떨어져...
-> 활용도를 높이자!
예시) 함수를 통해 재활용하여 활용도 더 높이기_외부에서 접근가능하게 만들자

ㄴ return cal; 생성된 객체의 참조주소를 반환하면 외부에서 접근해서 이 객체의 자원을 바로 접근 가능 -> 활용도가 더 높아진다

ㄴ 빨간색 네모칸 : 객체(힙)
ㄴ cal 변수에는 객체의 주소값이 있음
ㄴ 반환값 형태로 객체의 주소값을 빠져 나오게 하면 외부에서 접근 가능

ㄴ 다만 반환값(return)의 자료형이 Calculator이다
ㄴ void는 반환값이 없음 -> 반환값 자료형 맞춰주자

ㄴ void -> Calculator로 자료형 바꿈

ㄴ 이 식 왜 쓴거지?

ㄴ out.method();를 실행하면 실행과정중에 Calculator 인터페이스 클래스의 객체가 생성된다
ㄴ out.method();를 반환하면 return cal;이 반환되니까 생성된 객체(Calculator)의 주소값이 반환됨
ㄴ 근데 이걸 Calculator cal = out.method(); 로 안하고 그냥 out.method();만 하게 되면 즉 주소값을 대입하지 않게 되면 힙에 객체만 생성되고 참조가 끊긴 형태가 됨
-> 참조변수(주소값)를 외부에서도 대입하여 참조가 끊기지 않도록 해줘야 함

ㄴ 번외) 외부로 주소값만 내보내주면 되니까 굳이 변수에 담아서 return 할 필요 없이 바로 주소값 째로 return써도 ㅇㅋㅇㅋ
ㄴ 변수에 담아서 return하게 되면 공간을 할당받는데 굳이 안해도 되는데 하니까 공간낭비

ㄴ 외부에서 접근 가능하게 만듬
예시2) 보통은 실행과정(main함수 내에 정의)중에 인터페이스를 객체로 생성 많이 함

ㄴ 인터페이스 클래스를 객체로 만듬
ㄴ main함수의 지역내부

ㄴ 보통 이렇게 실행과정 중에 인터페이스를 객체생성하는 경우는 사용자 정의 할 때 쓴다
-> 매개변수와 반환값으로 쓰기 위해서
-> 함수형 프로그래밍 : 함수를 변수로 쓰는 것
= 인터페이스를 객체로 만들어서 매개변수, 반환값으로 쓰는 것
-> 람다식, 스트림

ㄴ 이거랑 동일하다고... : 람다식
매개변수도 정의해 보자ㅏㅏㅏㅏㅏ

ㄴ int num3 매개변수 정의함

ㄴ 매개변수에 30이란 값 넣음

ㄴ 이상하다 num3은 함수의 지역변수(스택)라서 호출되고 return하면(함수의 연산이 끝나면) 이제 사라지는데 왜 30이 계속 더해지지??

ㄴ 왜 이미 리턴됬는데 그 뒤에 식int result = cal.add(10, 20);랑int result2 = cal.add(10, 20);에서 값이 유지되지?

-> 지역변수가 아니란 말
-> 데이터 혹은 힙 영역이란 말
-> 자바쪽에서는 클래스 내부에 있는 메서드가 지역내부에서 쓰고 있다 그럼 제거 못함 왜? 쓰고 있으니까 없어지지 말라고
-> 데이터 영역(코드, 상수...)에 변수를 만들어 줌
-> 제거되지 않게 하기 위해 데이터 영역에 만듬(힙도 가비지 콜렉터가 제거 할 수 있으니까)
-> 상수화가 된다!
ㄴ 값을 유지하기 위해서 상수화가 된 것


ㄴ 상수화 되서 값을 바꿀 수 없음
예시2) 보통은 실행과정(main함수 내에 정의)중에 인터페이스를 객체로 생성 많이 함 + 지역변수의 상수화


ㄴ 지역변수의 상수화

보통은 실행과정(main함수 내에 정의)중에 인터페이스를 객체로 생성 많이 함
-> 사용자 정의 기능
예시) 인터페이스의 객체생성과 동시에 메서드 재정의

ㄴ Calculator cal = new Calculator(){} 에서 {}
= 객체를 생성하면서 동적으로 재정의한 것 -> 생성하면서 동시에 메서드를 재정의 한 것
예시) 일반 클래스도 생성과정 중에는 상속을 받지 않고도 생성과 동시에 메서드 재정의 가능


ㄴ 이 형태는 위 A클래스에 정의된 메서드 그대로 쓰는 것
ㄴ 근데 그 메서드를 바꾸고 싶음

ㄴ 보통은 상속을 통해서만 메서드 재정의가 가능했지만 생성과정중에는 상속하지 않고 메서드 재정의가 가능하다
= 객체를 만드는 과정중에도 메서드 재정의가 가능하다


ㄴ 재정의된 메서드가 출력됨
생성자를 정의하지 않은 경우 기본생성자를 추가해 줌
super()를 정의하지 않은 경우에만 모든 생성자 메서드의 첫줄에 super()를 추가해줌