본 글은 책 자바의 정석을 ref 하여 요약한 글입니다.
책의 내용은 아니지만 가장 먼저 절차적 프로그래밍과 객체지향 프로그래밍의 차이를 비교하고자 한다.
절차적 프로그래밍의 경우 공유 데이터 하나를 여러 함수를 통해서 조작하게 된다.
객체지향 프로그래밍에서는 객체는 자신의 데이터(상태)를 갖고 있고 이를 메서드를 통해 다른 객체와 상호작용한다.
데이터를 어떻게 다루냐에 있어서 차이가 있다.
절차적 프로그래밍 - 데이터, 함수가 분리
객체지향 프로그래밍 - 데이터, 함수가 결합
클래스와 객체
클래스 - 설계도, 데이터와 함수의 결합
객체 - 설계도에 따라 heap 영역에 인스턴스가 생성된 상태
* 자신을 참조하는 참조 변수가 없는 경우 인스턴스는 garbage collector에 의해 메모리에서 제거된다.
구성요소
속성 - 객체의 상태 값
기능 - 메서드
변수
클래스 변수 - 클래스가 메모리에 올라갈 때 생성
인스턴스 변수 - 인스턴스가 생성되면 생성
지역 변수 - 메서드가 호출되면 생성되었다가 메서드가 종료되면 소멸
메서드
중복된 코드를 재사용하며 구조화
인자로 주거나 결괏값을 받을 때 자동 형 변환이 되는 type으로 지정, 안된다면 형 변환 후 넘긴다.
JVM 메모리 구조
메서드 영역 - 클래스 변수, 클래스 정보
힙 영역 - 생성된 인스턴스
스택 영역 - 메서드(stack frame) 스택에 생성되고 처리 후 비운다.
기본형 매개변수와 참조형 매개변수
자바는 call by reference가 없다. 전부 call by value이며, 참조형 매개변수는 메모리의 주소가 아닌 객체 참조값을 넘긴다.
클래스(static) 메서드
인스턴스를 생성하지 않아도 사용 가능
클래스 메서드에는 인스턴스 변수를 사용할 수 없다. (클래스 메서드가 먼저 메모리에 올라감)
오버 로딩
같은 이름의 메서드명으로 인자의 type, 개수를 다르게 하여 여러 개의 메서드를 정의(리턴 타입은 영향 없다)
오버 라이딩
부모에게 상속받은 메서드를 재정의하여 사용한다.
이름, 매개변수, 리턴 타입이 같아야 한다.
생성자
객체의 인스턴스 변수를 초기화한다.
클래스의 이름과 같아야 한다.
기본 생성자는 컴파일러가 추가한다. 생성자를 하나라도 정의했다면 개발자가 기본 생성자를 작성해주어야 한다.
this() - 생성자 내부에서 다른 생성자를 호출한다. 가장 첫 줄에 작성한다.
상속
부모의 생성자, 초기화 블록을 제외한 멤버(속성, 기능)를 물려받는다.
** private로 선언된 멤버는 상속되지 않는다. (super로 접근하여 사용한다.)
** 부모 자식 클래스가 다른 패키지라면 default로 선언된 멤버는 상속되지 않는다.
** 자식 클래스 내부 - super.getter, super.setter || 외부 - getter, setter
자바에서는 단일 상속만을 허용한다.
클래스 간의 관계
포함관계 (has) - 상속하여 사용하지 않고, 속성에 다른 객체를 포함하여 해당 객체의 멤버를 사용한다.
상속관계 (is) - 상속관계라고 하지만 소속 관계라고 이해하고 있다.
super
부모, 자식과의 변수명이 같을 때 super, this를 이용해서 구분해줄 수 있다.
변수뿐만 아니라 오버 라이딩한 메서드의 구분도 가능하다.
super() - 부모 생성자를 호출하여 상속받은 부모 속성을 초기화할 수 있다. this()와 마찬가지로 가장 첫 줄에 위치한다.
패키지
클래스들의 묶음
클래스의 실제 이름은 패키지명을 포함
클래스 파일을 압축한 것이 jar
import
패키지가 다른 클래스를 사용할 때 패키 지명이 포함된 클래스를 작성하는 것이 불편해서 import를 이용한다.
import를 하게 되면 클래스명 만으로 사용 가능하다.
제어자
static - 클래스가 메서드 영역에 로드될 때 같이 로드된다. (속성, 메서드)
final - 변경될 수 없다는 의미 (클래스, 메서드, 변수)
abstract - 미완성의 의미 (클래스, 메서드)
접근제어자
public - 제한 없음
protected - 다른 패키지여도 상속한다면 사용이 가능하다. (클래스가 public 이어야 상속 후 protected 멤버 사용 가능)
default - 같은 패키지
private - 같은 클래스
다형성
하나의 참조타입로 여러 타입의 인스턴스를 사용 (클래스, 추상 클래스, 인터페이스)
업 캐스팅시 자식의 멤버는 사용할 수 없다. 오버 라이딩된 메서드는 사용 가능
참조 타입이 바뀌더라도 인스턴스는 바뀌지 않는다. (멤버 사용 범위가 달라질 뿐)
instanceof - 인스턴스를 이용해서 참조 타입으로 변환할 수 있는지 확인한다.
ex) 참조 변수(인스턴스) instanceof 참조 타입
다형성의 주의점
** 메서드를 오버 라이딩했다면 항상 자손의 오버 라이딩 메서드를 사용한다.
** 부모 메서드의 접근 제한자보다 오버 라이딩한 자식 메서드를 더 강한 접근 제한자를 설정할 수 없다.
** 오버 라이딩 메서드 내부에서 자신의 속성을 사용할 수 있다. (this)
** 같은 이름의 속성은 참조 타입에 의존한다.
추상 클래스
클래스들의 공통부분을 추상화해놓는다.
추상 클래스는 추상 메서드를 갖는다.
생성자를 가질 수 있다.
인스턴스를 생성할 수 없다.
* 동작이 동일한 부분은 일반 메서드로 구현해놓는다.
* 공통 부분이지만 인스턴스에 따라 달라지는 메서드는 추상 메서드로 선언한다.
인터페이스
추상 메서드와 상수만을 가질 수 있다. (static, default 메서드를 가질 수 있지만 복잡성을 줄이기 위해 일단 이렇게 이해)
** 추상 클래스와 인터페이스의 차이
추상 클래스는 클래스의 상속(소속) 관점 - (공통 기능을 구현해줄 수 있다.)
인터페이스는 단순히 기능 관점 - (필요 기능을 명시해줄 수 있다.)
추상 클래스는 재사용성의 관점에서 유용
인터페이스는 교체의 관점 유용
(추상클래스) 동물 - 사자, 독수리 소속 관점
(인터페이스) 독수리와 벌의 flyable 기능 관점(소속이 달라도 기능이 같다.)
추상 클래스는 상태 변수 필드를 갖고 있다.
인터페이스는 상태 값을 갖지 못하고 상수만 갖고 있다.
** 인터페이스의 이해
사용부(클라이언트 코드)에서는 내부를 알 필요가 없다. 메서드만 알면 된다.
인스턴스가 변경되더라도 메서드명은 같다. 유지보수가 편하다.
내부 클래스
가장 먼저 외부 클래스는 프로그램이 실행되면 메서드 영역에 올라간다는 점을 알면 이해하기 편하다.
* static이 인스턴스보다 먼저 로드된다.
인스턴스 클래스 - 외부 클래스 인스턴스가 생성되어야 사용 가능, 외부 클래스의 private 멤버도 접근 가능
스태틱 클래스 - 외부 클래스 인스턴스가 생성되지 않아도 사용 가능, 인스턴스 멤버에 접근 불가(static은 먼저 로드되기 때문)
지역 클래스 - 메서드가 종료되면 메서드 내부 지역변수를 지역 클래스가 알 수 없으므로 상수만 사용 가능하다. (지역 변수는 소멸될 가능성)
익명 클래스
하나의 객체만을 생성하는 일회용 클래스, 생성된 객체는 계속 사용할 수 있다. 설계도가 1회성
클래스를 상속받거나 인터페이스를 구현하여 사용한다.
람다식에 유용하게 사용된다.
'프로그래밍 > 자바' 카테고리의 다른 글
10장 날짜와 시간 & 형식화 (0) | 2022.07.28 |
---|---|
8장 예외처리, 9장 유틸클래스 (0) | 2022.07.28 |
3장 연산자, 4장 조건문과 반복문, 5장 배열 (0) | 2022.07.28 |
1장 자바, 2장 변수 (0) | 2022.07.28 |
[JAVA] 컬렉션 프레임 워크 <-> 배열 변환 (0) | 2022.07.13 |