본 내용은 자바의정석 책, 강의 기초편을 바탕으로 작성되었습니다. 
ch06. 객체지향 프로그래밍 I
 객체지향 언어 
객체지향 언어 = 프로그래밍언어 + 객체지향개념(규칙)
핵심 특징 : 캡슐화, 상속 , 추상화, 다형성 (OOP)
- 코드의 재사용성이 높다
- 코드의 관리가 용이하다
- 신뢰성이 높은 프로그래밍을 가능하게 한다
 클래스와 객체 
클래스 정의 : 클래스란 객체를 정의해 놓은 것
클래스 용도 : 클래스는 객체를 생성하는데 사용
객체의 정의 : 실제로 존재 하는 것, 사물 또는 개념
객체의 용도 : 객체가 가지고 있는 기능과 속성에 따라 다름
간단히 말하자면 클래스는 설계도 객체는 제품
Q. 클래스는 왜 필요한가?
A. 객체를 생성하기 위해
Q 객체가 왜 필요한가?
A 객체를 사용하기 위해
Q. 객체를 사용한다는 것은?
A. 객체가 가진 속성(변수)과 기능(메서드)을 사용하려고
 객체와 인스턴스 
객체와 인스턴스는 거의 같은말이다.
- 객체 : 모든 인스턴스를 대표하는 일반적 용어
- 인스턴스 : 특정 클래스로부터 생성된 객체 (예: TV인스턴스)
              인스턴스화
클래스/설계도 --------------> 인스턴스(객체)/ 제품
 객체의 생성과 사용 
- 객체의 생성
 클래수명 변수명;    	// 클래스 객체를 참조하기 위한 참조변수 선언 -> 참조형
 변수명 = new 클래스명();	 /./ 클래스의 객체를 생성 후, 객체 주소를 참조변수에 저장
 Tv t;
 t = new T();
- 객체의 사용
 t.channel = 7; // TV인스턴스의 멤버변수 channel의 값을 7로 한다.
 t.channelDown(); //Tv인스턴스 channelDown을 호출
 System.out.println(“현재 채널은 “ + t.channel + “입니다.”);
  
객체의 생성과 사용- 예제 
Tv t1 = new Tv();
Tv t2 = new TV();
t1.channel = 7;
사용 불가한 메모리는 가비지 컬렉터가 제거해준다.
 클래스의 정의(1) 
클래스 == 데이터 + 함수
- 설계도
- 데이터 +함수
- 사용자 정의 타입
변수 : 하나의 데이터를 저장할 수 있는 공간
배열 : 같은 종류의 데이터를 하나로 저장할 수 있는 공간
구조체 : 서로 관련된 여러 데이터(종류 관계X)를 하나로 저장할 수 있는 공간 -> 다른 타입도 가능
클래스 : 데이터와 함수의 결합(구조체 + 함수) -> 서로 관련있는 데이터
 클래스의 정의(2) 
사용자 정의 타입 – 원하는 타입을 직접 만들 수 있다.
 선언 위치에 따른 변수의 종류 
class Variavles{
		// 크게 3가지로 나뉜다, 선언문의 순서는 상관 X
		int iv; // 1. 인스턴스 변수, 클래스 영역
		static int cv; // 클래스 변수 (static변수, 공유 변수) , 클래스 영역
			
		void method() {
			int lv; // 지역변수 , 메서드 영역
		}
	}
- 클래스 영역: iv, cv(static+iv)
- 메소드 영역: lv(지역변수)
 cv : 클래스가 메모리에 올라갈때 생성(객체 생성 전), 객체생성 필요x
 iv : 객체 생성될때마다 생성
 객체 = iv를 묶어놓은 것
 클래스 변수와 인스턴스 변수 
- iv는 개별, cv는 공통속성
 Cv는 사용시 앞에 클래스 이름 붙여야함(안해도 오류는 안나지만 권장안함)
 메서드란?
- 문장들을 묶어 놓는 것.
 작업 단위로 문장들을 묶어서 이름 붙인 것
- 값(입력)을 받아서 처리하고, 결과를 반환(출력)
메서드 = 선언부 + 구현부
반환타입 메서드이름 (타입변수명,…) //선언부
{
// 구현부
}
return 문
실행 중인 메서드를 종료하고 호출한 곳으로 되돌아 간다.
반환타입이 void가 아닌경우, 반드시 return 문 필요하다.
호출 스택(call stack)
메서드 수행에 필요한 메모리가 제공되는 공간
메서드가 호촐되면 호출스택에 메모리 할당, 종료되면 해제
아래에 있는 메서드가 위의 메서드를 호출 -> 맨위의 메서드가 종료될때까지 아래 메서드는 대기
스택(stack): 밑이 막힌 상자. 위에 차곡차곡 쌓인다.(LIFO)
기본형 매개변수
- 기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.(read only)
- 참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다.(read &write)
static -> 객체 생성없이 호출 가능
static 메서드와 인스턴스 메서드
	인스턴스 메서드
- 인스턴스 생성 후, ‘잠조변수.메서드이름()’으로 호출
- 인스터스 멤버(iv,im)와 관련된 작업을 하는 메서드
- 메서드 내에서 인스턴스 변수(iv) 사용 가능
	Static 메서드(클래스 메서드)
- 객체 생성 없이 ‘클래스이름.메서드이름()’으로 호출
- 인스턴스 멤버(iv,im)과 관련 없는 작업을 하는 메서드
- 메서드 내에서 인스턴스 변수(iv) 사용 불가
즉 iv 사용여부 차이다. Iv를 사용하지 않을 때 static 붙여준다.
static을 언제 붙여야 할까
- 속성(멤버변수) 중에서도 공통속성에 static을 붙인다.
- 인스턴스 멤버(iv,im)을 사용하지 않는 메서드에 static을 붙인다.
 메서드 -> 명령문 집합
메서드간의 호출과 참조
- Static 메서드는 인스턴스 변수(iv)를 사용할 수 없다.
- Static 메서드는 인스턴스 메서드(im)를 호출할 수 없다.
왜 static 메서드는 인스턴스 멤버를 쓸 수 없나요?
static메서드 호출시 객체(iv묶음)가 없을수도 있어서
오버로딩
한 클래스 안에 같은 이름의 메서드를 여러 개 정의하는 것 (매개변수가 다름)
- 오버로딩이 성립하기 위한 조건
 1.	메서드 이름이 같아야 한다.
 2.	매개변수의 개수 또는 타입이 달라야 한다.
 3.	반환 타입은 영향없다.
생성자(constructor)
인스턴스가 생성될 때마다 호출되는 ‘인스턴스 초기화 메서드’
인스턴스 생성시 수행할 작업(iv 초기화)에 사용
클래스이름(타입 변수명, 타입변수명,..){
		// 인스턴스 생성 시 수행될 코드,
		// 주로 인스턴스 변수의 초기화 코드를 적는다.
}
기본 생성자(constructor)
- 매개변수가 없는 생성자
- 생성자가 하나도 없을 때만, 컴파일러가 자동 추가
클래스 이름(){ } // 기본 생성자
Point(){ } // Point 클래스의 기본 생성자
생성자 this()
- 생성자에서 다른 생성자 호출할 때 사용
- 다른 생성자 호출시 첫 줄에서만 사용가능
참조변수 this
- 인스턴스 자신을 가리키는 참조변수
- 인스턴스 메서드(생성자 포함)에서 사용 가능
- 지역변수(lv)와 인스턴스 변수(iv)를 구별할 때 사용
 iv는 같은 클래스 내에서는 생략 가능
참조변소 this와 생성자 this()
this 인스턴스 자신을 가리키는 참조변수. 인스턴스 주소가 저장되어 있다.
모든 인스턴스 메서드에서 지역변수로 숨겨진채로 존재한다.
this(), this(매개변수) 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
변수의 초기화
지역변수(lv)는 수동 초기화 해야함(사용전 꼭!!)
멤버변수(iv,cv)는 자동 초기화된다
멤버변수의 초기화
- 명시적 초기화(=)
Class Car{
Int door = 4; // 기본형 변수의 초기화
Engine e = new Engine(); // 참조형 변수의 초기화
}
- 초기화 블록
- 인스턴스 초기화 블록 : { }
- 클래스 초기화 블록 : static { }
 
- 생성자 -> iv 초기화, 복잡한 초기화에 사용
멤버변수의 초기화
- 클래스 변수 초기화 시점: 클래스가 처음 로딩될 때 단 한번
- 인스턴스 변수 초기화 시점: 인스턴스가 생성될 때 마다
초기화 순서: cv -> iv / 자동(기본0으로 초기화) -> 간단(대입연산자 선언) -> 복잡(static{ }, 생성자)
Ch07. 객체지향 프로그래밍 02
상속
- 기존 클래스로 새로운 클래스를 작성하는 것.(코드의 재사용)
- 두 클래스를 부모와 자식으로 관계를 맺어주는 것.
- 자손은 조상의 모든 멤버를 상속받는다.(생성자, 초기화 블록 제외)
- 자손의 멤버 개수는 조상보다 적을 수 없다.(같거나 많다.)
- 자손의 변경은 조상에 영향을 미치지 x
class parent{
	int age;
}
class Child extends Parent {}
클래스간의 관계 – 상속관계(inheritance)
- 공통부분은 조상에서 관리하고 개별부분은 자손에서 관리한다.
- 조상의 변경은 자손에 영향을 미치지만, 자손의 변경은 조상에 아무런 영향을 미치지 않는다.
클래스간의 관계 – 포함관계(composite)
- 한 클래스의 멤버변수로 다른 클래스를 선언하는 것
- 작은 단위의 클래스를 먼저 만들고, 이 들을 조합해서 하나의 커다란 클래스를 만든다.
클래스 간의 관계 결정하기 :
- 상속관계 : ~은 ~이다(is-a)
- 포함관계 : ~은 ~을 가지고 있다(has-a)
오버라이딩(overriding)이란?
 상속받은 조상의 메서드를 자신에 맞게 변경하는 것 (선언부는 변경 불가하고 내용만 변경 가능)
오버라이딩(overriding)의 조건
- 선언부가 조상 클래스의 메서드와 일치 해야 한다.
- 접근 제어지를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
- 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.
오버로딩 vs 오버라이딩
오버로딩 – 기존에 없는 새로운 메소드를 정의하는 것(new)
오버라이딩 – 상속받은 메서드의 내용을 변경하는 것 (change, modigy)
->	이름만 비슷할 뿐 전혀 다름
super() – 조상의 생성자
- 조상의 생성자를 호출할 때 사용
- 조상의 멤버는 조상의 생성자를 호출해서 초기화
- 조상의 생성자는 조상이 초기화 하는게 좋음, 자신이 선언한 것만 초기화.
- 생성자 첫줄에 반드시 생성자를 호출해야한다. 그렇지 않으면 컴파일러가 생성자의 첫줄에 super(); or this() 삽입
패키지
- 서로 관련된 클래스의 묶음
- 클래스 -> 클래스 파일(*.class), 패키지는 폴더
- 클래스의 full name은 패키지를 포함
패키지 선언 
-  패키지는 소스파일의 첫 번째 문장으로 단 한 번 선언 
-  패키지 선언이 없으면 디폴트 패키지에 속하게 됨
클래스 패스
- 클래스파일(*.class)의 위치를 알려주는 경로(path)
- 환경변수 classpath로 관리하며, 경로간의 구문자는 ‘;’를 사용
import 문
- 클래스를 사용할 때 패키지 이름을 생략할 수 있다.
- 컴파일러에게 클래스가 속한 패키지를 알려준다.
->	Ctrl +shift +o(알파벳) 누르면 자동 임폴트 생성
import static 
static멤버 사용을 간결하게 하기 위해(클래스 이름 사용 생략)
static – 클래스의, 공통적인
클래스 : 다른클래스의 조상이 될 수 없다
메서드 : 오버라이딩을 통해 재정의 될 수 없다.
멤버변수, 지역변수 : 변수 앞에 final이 붙으면, 값을 변경할 수 없는 상수가 된다.
final – 마지막의, 변경될 수 없는
클래스 : 다른클래스의 조상이 될 수 없다
메서드 : 오버라이딩을 통해 재정의 될 수 없다.
멤버변수, 지역변수 : 변수 앞에 final이 붙으면, 값을 변경할 수 없는 상수가 된다.
abstract : 추상의, 미완성의(추상화)
추상클래스 - 추상메서드를 가지고있는 클래스.
추상메서드 - 구현부가 없는 메서드.  상속을 통해 추상클래스를 완성 시킨 후에 객체생성가능.
접근 제어자
- private : 같은 클래스(파일)안에서만
- default : 같은 패키지(폴더)안에서만
- protected : 같은 패키지 + 다른패지키에서는 자식클래스 안에서만
- public : 접근제한 XX
캡슐화와 접근 제어자
접근 제어자를 사용하는 이유
- 외부로부터 데이터를 보호하기 위해서
- 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서
 접근 범위는 좁을수록 좋음 -> 테스트 범위가 줄어든다.
다형성
- 여러가지 형태를 가질 수 있는 능력
- 조상 타입 참조변수로 자손 타입 객체를 다루는 것
- 자손타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.
참조변수의 형변환
- 사용할 수 있는 멤버의 개수를 조절하는 것 , 값이 바뀜
- 조상 자손 관계의 참조변수는 서로 형변환 가능 
- 자손 -> 조상 사용 멤버의 개수 감소 (안전)
- 조상 -> 자손 사용 멤버의 개수 증가 (안전하지 않음)
-> 참조변수의 형변환 팁 : 실제 객체가 가지고 있는 멤버의 갯수의 max값을 넘지 않으면서 조절이 가능하면 된다
instance of 연산자
- 참조 변수의 형변환 가능여부 확인에 사용. 가능하면 true 반환
- 형변환 전에 반드시 instanceof 확인해야 함
참조변수의 형변환은 왜 하나요?
- 참주변수(리모컨)을 변경함으로써 사용할 수 있는 멤버 개수를 조절하기 위해서
매개변수의 다형성
다형성의 장점 : 다형적 매개변수, 하나의 배열로 여러종류 객체 다루기
- 참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.
여러 종류의 객체를 배열로 다루기
조상타입의 배열에 자손들의 객체를 담을 수 있다.
Vector class
추상 클래스
- 미완성 설게도. 미완성 메서드를 갖고 있는 클래스
- 구현부(몸통, {})이 없는 미완성 메서드
 abstract 리턴타입 메서드 이름();
- 다른 클래스 작성에 도움을 주기 위한 것. 인스턴스 생성 불가
- 상송을 통해 추상 메서드를 완성해야 인스턴스 생성 가능
- 추상메서드 호출시 선언부만 필요
추상 클래스의 작성
- 추상 클래스를 사용하면 중복을 제거와 변경이 쉬움.
- 추상 클래스를 단계별로 여러 개 만들면 필요한 것만 상속해서 구현도 가능 = 수정에 용이.
- 추상화 <- -> 구체화
- 추상화된 코드는 구체화된 코드보다 유연하다. 변경에 유리
인터페이스
- 추상메서드의 집합
- 구현된 것이 전혀 없는 설계도. 껍데기( 모든 멤버가 public)
추상클래스 vs 인터페이스(차이점)
- 추상클래스는 생성자 및 iv가 있지만 인터페이스는 구현것이 아무것도 없이 추상메서드만 나열
Interface 인터페이스이름{
	public static final 타입 상수이름 = 값; //상수
	public abstract 메서드이름(매개변수목록); //추상메서드
}
인터페이스의 상속
- 인터페이스의 조상은 인터페이스만가능(Object가 최고 조상 아님)
- 다중 상속 가능.(추상메서드는 충돌해도 문제 없음)
인터페이스의 구현
Class 클래스이름 implements 인터페이스이름{
	//인터페이스에 정의된 추상메서드를 모두 구현해야 한다.
	//일부만 구현할 경우 미구현에 abstract를 붙인다.
}
인터페이스를 이용한 다형성
- 인터페이스 참조변수로 인터페이스를 구현한 인스턴스를 참조할 수 있다 (다형성)
 -> 인터페이스에 정의된 메서드만 접근이 가능하다
- 인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능하다
- 인터페이스를 메서드의 리턴타입으로 지정할 수 있다
 -> 인터페이스를 구현한 클래스의 인스턴스를 반환
인터페이스의 장점
- 
두 대상(객체)간의 ‘연결,대화,소통’을 돕는 ‘중간역할’을 한다. 
- 
선언(설계)와 구현을 분리시킬 수 있게 한다. 
- 
알멩이가 바뀌어도 껍데기가 그대로면 사용에 아무 지장없다(변경에 유리) 
- 
인터페이스 덕분에 B가 변경되어도 A는 안바꿀 수 있게 된다.(느슨한 결합) 
- 
개발 시간을 단축할 수 있다. 
- 
변경에 유리한 유연한 설계가 가능하다. 
- 
표준화가 가능하다. 
- 
서로 관련없는 클래스들을 관계를 맺어줄 수 있다. Ex) JDBC(인터페이스의 집합 –표준) 
디폴트 메서드와 static 메서드
- 인터페이스에 디폴트 메서드, static메서드 추가 가능(jdk1.8부터)
 -인터페이스에 새로운 메서드(추상메서드)추가하기 어려움 -> 해결책 : 디폴트 메서드
- 디폴트 메서드는 인스턴스 메서드(인터페이스 원칙 위반)
-> 디폴트 메서드가 기존의 메서드와 충돌할때는 직접 오버라이딩하면 해결 가능