이 글은 "Java의 정석 (남궁 성 지음)"을 읽고 주관적으로 요약한 글입니다.
1. 객체지향 언어
- 과학자들의 모의실험을 위해 가상 세계를 컴퓨터 속에 구현하며 객체지향이론 탄생
- 객체지향이론의 기본 개념
- 실세계는 사물(객체)로 이루어져있고, 발생하는 모든 사건은 사물간의 상호작용이다
- 객체지향언어
- 코드 간의 서로 관계를 지어 유기적으로 프로그램을 구성하는 것이 가능해짐
- 객체지향언어의 특징
- 코드의 재사용율이 높음
- 기존 코드를 이용하여 쉽게 작성 - 코드 관리가 용이
- 코드간의 관계를 이용하여 쉽게 코드 변경 - 신뢰성이 높은 프로그래밍
- 제어자/메서드로 데이터 보호, 올바른 값 유지 및 코드 불일치로 인한 오작동 방지
- 코드의 재사용율이 높음
2. 클래스와 객체
1) 클래스와 인스턴스의 정의
- 클래스
- 객체를 정의해놓은 것
- 객체의 설계도
- 설계도만 잘 만들어 놓으면 제품을 만드는 일이 쉬워짐
- 인스턴스(객체)
- 클래스에 정의된 내용대로 메모리에 생성된 것
- 클래스 -> (인스턴스화) -> 인스턴스
- 객체의 구성요소
- 객체는 속성과 기능의 집합이며, 객체가 가진 속성과 기능을 멤버라고 함
- 속성
- 멤버변수 - 기능
- 메서드
2) 인스턴스의 사용
- 인스턴스의 생성과 사용
- 인스턴스의 생성 (new 연산자)
- 변수명 = new 클래스명();
- 연산자 new에 의해 클래스의 인스턴스가 메모리의 빈 공간에 생성
- 멤버변수는 자료형의 기본값으로 초기화 - 인스턴스의 사용
- 참조변수를 통해서만 접근 가능
- 참조변수의 타입은 인스턴스의 타입과 일치해야함 - 인스턴스의 제거
- 참조하는 참조변수가 하나도 없는 인스턴스는 사용할 수 없음
- 가비지 컬렉터에 의해 자동으로 메모리에서 제거
- 인스턴스의 생성 (new 연산자)
- 객체 배열
- 배열에 객체 주소가 저장됨
- 즉, 참조변수들을 하나로 묶은 참조변수 배열
- 객체 배열 선언
- 클래스명[] 변수명 - 객체를 생성해서 객체 배열의 각 요소에 저장하는 것이 필수
- ex) for(int i=0; i<tvArr.length; i++){
tvArr[i] = new Tv();
}
3) 클래스의 장점
- 클래스를 사용했을 때 장점은 다음 3가지
- 데이터와 함수의 결합
- 사용자정의 타입
- 데이터 유효성
- 데이터와 함수의 결합
- 변수 -> 배열 -> 구조체 -> 클래스
- 데이터는 데이터끼리, 함수는 함수끼리 따로 다루어져왔으나, 데이터와 함수는 관계가 깊음 - 사용자정의 타입
- 구조체와 같이 사용자가 타입을 정의할 수 있음 - 데이터 유효성
- 데이터에 대한 제약조건을 반영할 수 있음
- 포멧, 범위, 양수/음수 등등
- 제어자를 통해 변수를 직접 변경하지 못하고 메서드를 통해 값을 변경하도록 작성
- 메서드에서 값의 유효성을 조건문으로 점검
3. 변수와 메서드
1) 변수
- 변수의 종류
- 선언 위치에 따라 다음 3가지로 나뉨
- 지역 변수
- 멤버 변수를 제외한 나머지 변수 - 클래스 변수
- 멤버 변수 중 static이 붙은 것 - 인스턴스 변수
- static이 붙지 않은 것
- 지역 변수
- 선언 위치에 따라 다음 3가지로 나뉨
변수의 종류 | 선언위치 | 생성시기 | |
멤버 변수 | 클래스 변수 | 클래스 영역 | 클래스가 메모리에 올라갈 때 |
인스턴스 변수 | 인스턴스가 생성되었을 때 | ||
지역 변수 | 클래스 영역 이외의 영역 (메서드, 생성자, 초기화블럭) |
변수 선언문이 수행되었을 때 |
class Variables
{
int instanceValue; // 인스턴스 변수
static int classValue; // 클래스 변수
void method()
{
int localValue = 0; // 지역 변수
}
}
- 인스턴스 변수
- 생성 시기
- 클래스의 인스턴스를 생성할 때 만들어짐 - 사용
- 사용하기 위해서는 인스턴스를 먼저 생성해야함 - 인스턴스마다 독립적인 값
- 인스턴스는 독립적인 저장공간을 가지므로 독립적인 상태(서로 다른 값)을 가짐
- 생성 시기
- 클래스 변수
- 생성 시기
- 클래스가 메모리에 로딩될 때 생성
- 클래스가 메모리에 로딩되는 시점 : 참조변수의 선언 / 객체의 생성 등 클래스 정보가 필요할 때 - 사용
- 인스턴스를 생성하지 않고 바로 사용 가능 - 인스턴스 모두가 같은 값
- 모든 인스턴스가 공통된 저장공간(변수)를 공유
- 따라서, 모든 인스턴스가 공통적인 값을 유지해야할 때 사용 - public을 붙일 경우, 전역 변수의 성격을 가지며 같은 프로그램 내에서 어디서나 접근 가능
- 생성 시기
2) 메서드
- 메서드 정의
- 특정 작업을 수행하는 일련의 문장을 하나로 묶은 것
- 필요한 값으로 원하는 결과만 얻으면 됨
- 결과를 만드는 세부 과정은 몰라도 됨(블랙박스)
- 메서드를 사용하는 이유 (함수 사용 이유와 같음)
- 높은 재사용성
- 한 번 만들면 계속 재사용이 가능하고 다른 프로그램도 사용 가능 - 중복 코드 제거
- 중복된 문장을 줄여 가독성을 높임 - 프로그램의 구조화
- 큰 규모의 프로그램에서 여러 메서드를 담아 구조를 단순화 시키는 것이 필수적
- 먼저 내용이 없는 메서드를 작업단위로 만들고, 하나씩 완성해가는 것도 구조화의 좋은 방법
- 높은 재사용성
- 메서드 선언과 구현
- 매개변수도 지역 변수다
- 메서드 이름은 기능을 쉽게 알 수 있는 함축적이면서 의미있는 이름을 지어야 함
- 메서드의 호출
- 인자(argument)와 매개변수(parameter)
- 인자 : 메서드를 호출할 때 괄호()안에 지정해준 값
- 메서드에 정의된 매개변수의 개수/순서와 일치해야함 - 메서드의 실행 흐름
- 같은 클래스 내에서 메서드끼리 서로 호출 가능
- 그러나 static메서드(클래스 메서드)는 인스턴스 메서드를 호출할 수 없음
- 인자(argument)와 매개변수(parameter)
- 매개변수의 유효성 검사
- 메서드에서 제일 먼저 해야할 일은 매개변수에 대한 유효성 검사
- '호출하는 쪽에서 알아서 적절한 값을 넘겨주겠지'라는 생각을 절대로 가져서는 안됨
- 0으로 나누는 것은 금지되어 있기 때문에, 확인하지 않으면 프로그램이 비정상적으로 종료
3) JVM의 메모리 구조
- 응용 프로그램이 실행될 때 JVM
- 시스템으로부터 프로그램 수행에 필요한 메모리를 할당 받음
- 이 메모리를 용도에 따라 영역을 나누어 관리
- 메서드 영역 (method area)
- 호출 스택 (call stack 또는 execution stack)
- 힙 (heap)
- 메서드 영역 (method area)
- 프로그램 실행 중 어떤 클래스가 사용되면
- JVM이 해당 클래스파일을 읽고 분석해서
- 클래스에 대한 정보(클래스 데이터)를 이곳에 저장
- 클래스 변수도 포함
- 힙 (heap)
- 프로그램 실행 중 모든 인스턴스가 생성되는 공간
- 인스턴스 변수도 포함
- 호출 스택 (call stack 또는 execution stack)
- 메서드의 작업에 필요한 메모리 공간 제공
- 메서드 호출시
- 호출된 메서드의 메모리 할당
- 지역변수(매개변수 포함) / 연산 중간 결과 등을 저장 - 작업을 마치면 메모리 반환
4) 기본형 변수와 참조형 변수
- 메서드 호출 시 매개변수
- 기본형 매개변수는 값이 복사됨
- 읽기만 가능 (read-only) - 참조형 매개변수는 주소가 복사됨
- 읽기/쓰기 가능 (read/write)
- 기본형 매개변수는 값이 복사됨
- 참조형 반환타입
- 반환타입도 참조형이 될 수 있음
- 모든 참조형 타입의 값은 '객체의 주소'
- 호출 결과를 저장하는 변수의 타입과 반환되는 참조변수의 타입이 일치해야함
class Data { int x; }
class ReferenceReturnEx{
public static void main(String[] args){
//...
Data d = new Data();
Data d2 = copy(d);
//...
}
static Data copy(Data d){
Data tmp = new Data();
tmp.x = d.x;
return tmp;
}
}
- 재귀호출
- 메서드 입장에서는 자기자신을 호출하는 것과 다른 메서드를 호출하는 것이 차이가 없음
- 호출한 메서드(caller)와 관계없이 독립적인 작업 수행
- 호출된 메서드(callee)는 '값에 의한 호출(call by value)'을 통해
- 원래의 값이 아닌 복사된 값으로 작업 - 매개변수 복사 / 종료 후 복귀할 주소저장 등으로 인해 반복문보다 오래걸림
- 그러나 논리적 간결함으로 오류 발생도 적고 수정도 쉬워 사용
- 재귀호출 예시
- 피보나치
- 매개변수 n의 상한을 12로 유효성 검사가 필요 (약 20억보다 크기 때문)
- 또한 stackoverflow 주의 -> 재귀호출은 반복문으로 작성하면 됨
5) 클래스 메서드와 인스턴스 메서드
- 클래스 메서드
- 객체를 생성하지 않고도 호출 가능 (클래스 참조변수 선언 or 클래스 이름 사용)
- 인스턴스 변수를 사용할 수 없음
- 인스턴스 메서드
- 인스턴스 변수 / 인스턴스 메서드를 사용하는 작업을 하는 메서드
- 클래스 설계시 static을 붙이는 경우
- 모든 인스턴스에 공통으로 사용되는 변수에는 static을 붙임
- 인스턴스 변수를 사용하지 않는 메서드는 static을 붙이는 것을 고려해야 함
- Math 클래스
- Math 클래스의 모든 메서드는 클래스 메서드
- 인스턴스 변수 없이 모두 매개변수로 처리
- 클래스 멤버의 인스턴스 멤버 호출
- 아래와 같이 인스턴스 멤버 호출이 가능하긴 하지만, 클래스 변수로 다시 설계가 필요한지 검토가 필요
class MemberCall{
int instanceValue = 10;
// static int classValue = instanceValue; -> 불가능
static int classValue = new MemberCall().iv; // 가능
}
'책읽기' 카테고리의 다른 글
[파이썬 알고리즘 인터뷰] 18장 - 이진 검색 (0) | 2021.08.12 |
---|---|
[Java의 정석][Chapter-6] 객체지향 프로그래밍1 (2/2) (0) | 2021.08.09 |
[파이썬 알고리즘 인터뷰][정렬] 원점에 K번째로 가까운 점 (0) | 2021.08.07 |
[파이썬 알고리즘 인터뷰][정렬] 색 정렬 (0) | 2021.08.07 |
[파이썬 알고리즘 인터뷰][정렬] 유효한 애너그램 (0) | 2021.08.07 |