객체지향이란 현실 세계의 객체 모델을 바탕으로 프로그램을 구조화하고 개발하는 프로그래밍 기법 , 객체들을 사용하여 하나의 완성품을 만드는 프로그래밍 기법
객체는 해당 객체가 가지고 있는 속성과 객체가 할 수 있는 동작으로 설명 , 우리눈에 보이는 모든 것들

-> 빨간색 소나타 뿐 아니라 파란색 소나타도 있고, 검은색 제네시스도 있고 등등 공통적인 성질을 가지고 있지만 구체적인 값들이 다른 여러 객체가 있을 수 있다 따라서 공통적인 속성 , 동작을 가지는 상위 개념을 정의할 수 있는데 그것이 바로 클래스이다.
객체를 정의하기 위한 틀

-> 클래스를 통해 여러 객체를 생성할 수 있는데 클래스를 통해 생성된 객체를 인스턴스라고 한다.
클래스를 통해 만들어진 구체적인 객체

상속은 클래스간의 상하 관계로 추상적인
슈퍼 클래스혹은 부모 클래스로 부터서브 클래스혹은 자식 클래스를 만드는 것으로 상속이라는 관계를 통해 계층구조를 형성
코드의 재사용 , 부모클래스 레벨에서 호환되는 서브클래스 사용으로 다형성 기반 마련

-> extends 키워드를 사용하고 자바의 겨우 두개 이상의 클래스를 동시에 상속받는 다중 상속은 지원 x , 대신 인터페이스를 이용해 여러 클래스의 속성을 가지는 서브 클래스 구현 가능
슈퍼 클래스로 부터 상속받은 메서드를 다시 정의하는 것
메서드 이름과 리턴 타입, 인자등이 모두 동일해야 하며 다른 경우는 새로운 메서드가 추가되는 형식
ex) 애완동물 클래스가 있고, bark() 라는 메서드가 있다고 할 때 애완동물 클래스를 상속 받는 강아지와 고양이 클래스를 만들 경우 bark()메서드의 오버라이딩을 통해 서로 다른 동작이 가능하게 할 수 있다.

추상 클래스는 추상 메서드를 포함하고 있는 클래스
구체적이지 않은 내용을 정의한 메서드를 말하는 것으로 추상 메서드로 정의된 메서드는 서브 클래스에서 반드시 오버라이딩을 통해 구현해야 한다

무언가를 이어주기 위한 연결고리로 추상 클래스와 유사하지만 상수와 추상메서드로만 구성된 형태 추상 메서드로만 구성되기 때문에 그 자체로는 아무런 기능 x 하지만 설계도처럼 향후 구현될 클래스들을 연결해 사용할 수 있는 기반 구조 제공
public static final만 가능하며 제어자는 생략 가능public abstract만 가능하고 제어자는 생략 가능

일반적인 클래스들은 다중상속이 불가하지만 인터페이스의 경우 다중 구현이 가능하다
ex) 로봇 애완견을 만들기 위해 pet과 robot 인터페이스를 동시에 구현할 수 있다

-> 양쪽 인터페이스 모두 추상 메서드가 구현되어야 하고 상속받을 클래스가 있다면 상속과 함께 사용하는 것도 가능

일반적으로 설계의 관점에서는 인터페이스를 사용하고 구현시 유연함을 위해서는 추상클래스를 사용할 수 있다.
다만 JDK 8에서 추가된 default를 이용하면 인터페이스에 메서드 구현이 가능하고 이를 구현하는 클래스에서 해당 메서드의 오버라이딩도 가능해져 사실상 추상클래스의 역할을 겸하게 되었다고 볼 수 있다.
추가적으로 static 메서드의 구현도 가능해져 인터페이스의 활용도가 높아졌다

패키지는 자바 클래스들을 구분하기 위해 사용
ex) 회원관리 프로그램에 Login클래스가 있을 수 있으며 카페나 블로그, 쇼핑몰 쪽에서도 Login클래스가 있을 수 있다. 이처럼 서로 다른 목적에서 개발된 클래스들을 서로 구분하기 위해 사용
네이버의 도메인 : naver.com , 루트 패키지명 : com.naver

제어자는 클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여
public, static 같은 키워드가 해당
클래스 혹인 공통적인 의미를 가지고 있으며 , 클래스 변수나 메서드 선언에 사용
변경할 수 없다는 의미를 가지고 있으며 변수, 메서드 , 클래스에 사용
추상 클래스와 추상 메서드를 선언할 때 사용
멤버 또는 클래스에 사용하며 외부에서의 접근을 제어하기 위해 사용
캡슐화는 객체지향 프로그램의 대표적인 특징중 하나 , 접근 제어자를 사용하면 클래스 외부로부터의 접근을 제어할 수 있으므로 객체를 캡슐화 할 수 있다.
ex) private의 경우 동일 클래스 내에서만 접근이 가능하므로 멤버필드에 private를 선언하면 해당 변수를 클래스 외부에서 접근할 수 없게 된다.
-> 이 경우 클래스 외부에 해당 멤버의 접근을 제공하기 위해 getter, setter 메서드를 제공하는 방식을 사용한다 getter 는 멤버값을 제공 , setter는 멤버값의 변경을 위해 사용
