일단 이것저것 해 보는 블로그

(Do it! 자바, 2주차) 객체 지향 프로그래밍과 관련 개념 이해 (250109~250116) 본문

2026/Do it Java 스터디(2026.01.~02.)

(Do it! 자바, 2주차) 객체 지향 프로그래밍과 관련 개념 이해 (250109~250116)

뷔구룽 2026. 1. 9. 22:39

2주차 공부 인증샷

 

개요

 

2주차는, 본격적으로 객체 지향 프로그래밍을 이해하고 관련 개념에 익숙해지는 과정을 거친다.

(본격적으로 자바를 배우기 시작한다는 느낌이 들지만... 다음을 읽으면 알 수 있듯 기억해야 할 개념이 너무 많아 힘들다.)

 

사용한 학습 자료: 박은종, 2025, <Do it! 자바 프로그래밍 입문 [개정판]>, 이지스퍼블리싱.

https://ebook-product.kyobobook.co.kr/dig/epd/ebook/E000010942415

 

Do it! 자바 프로그래밍 입문 [개정판] | 박은종 저자

eBook Do it! 자바 프로그래밍 입문 [개정판] | 3만 6천 부 이상 팔린 초판의 성공에 힘입어 좀 더 입문자의 눈높이에 맞춰 내용을 수정하고 최신 개발 트렌드에 맞게 개정판을 출간했습니다. 저자인

ebook-product.kyobobook.co.kr

 

 

개념 요약 정리

최대한 공부한 개념을 간략히 요약해 보았지만, 역시 양이 많은 건 어쩔 수가 없다...!

결국 중요한 건 직접 예제를 실습해보며 개념을 몸으로, 손가락으로 체득하기

<5장: 클래스와 객체 1>

0) 기본 용어 정리
객체: 객체 지향 프로그램의 대상, 생성된 인스턴스
클래스: 객체를 프로그래밍하기 위해 코드로 만든 상태
인스턴스: 클래스가 메모리에 생성된 상태
인스턴스 변수: 클래스의 속성, 특성
메서드: 인스턴스 변수를 이용하여 클래스의 기능을 구현한 것
참조 변수: 메모리에 생성된 인스턴스를 가리키는 변수
참조값: 생성된 인스턴스의 메모리 주솟값

 

1) 객체 지향 프로그래밍
객체 지향 프로그래밍: 어떤 대상(객체)를 정의하고 객체 간 협력을 프로그래밍, 먼저 객체를 만들고 객체 사이에서 일어나는 일을 구현
-> 객체란 '의사나 행위가 미치는 대상'으로, 객체 지향 프로그램의 대상을 가리킴
cf) 절차 지향 프로그램: 순서대로 일어나는 일의 시간순서로 프로그래밍하는 것 ex) C

클래스: 객체의 속성과 기능을 코드로 구현한 것. '클래스를 정의(객체를 클래스로 구현)'
멤버 변수(= 인스턴스 변수): 선언하는 클래스의 속성
ex) 학생이라는 객체를 클래스로 구현-> 학생의 속성(학번, 이름, 학년, 사는 곳 등)을 Student 클래스로 구현, 속성은 클래스 내부에 변수(인스턴스 변수)로 선언하기도 함.

클래스 정의하는 문법:

{접근 제어자(public 등)} class 클래스 이름 {
관계 변수;
메서드;
} // 교재(이지스퍼블리싱, 2025)의 내용을 개인 학습용으로 정리.

* public class인 경우, 클래스 이름 = 자바 파일 이름

클래스 이름 짓는 규칙
"클래스 이름은 대문자로 시작한다"
-> 개발자들 사이의 불문률(코딩 컨벤션: 코딩할 때 읽고 이해하기 쉽도록 정한 규칙)


2) 클래스
멤버 변수를 선언할 때는 속성에 맞는 자료형을 사용한다. -> 학번: int, 이름: 문자열(여러 개 문자로 이루어짐; String), 학년: int 등

참조 자료형(클래스형): JDK애서 기본 제공하는 클래스(String, Date 등)나 직접 만든 클래스를 사용해 멤버 변수 선언할 때 사용.

메서드(멤버 함수): 클래스 내부에서 멤버 변수를 사용해 클래스 기능을 구현한 것.

패키지: 클래스 파일의 묶음, 계층 구조를 가질 수 있음.
ex) '학생 관리' 안에 학생, 과목, 교실, 담당 교수, 학과 등 클래스가 포함될 수 있음. 혹은 그 클래스와 협력하는 여러 다른 클래스가 존재하기도 함.
-> 패키지는 프로젝트 전체 소스 코드를 구성하는 계층 구조로, 이를 잘 구성해야 소스 코드 관리와 유지보수가 편리해짐.
-> 자바 코드에서 패키지는 맨 윗줄에서 선언
ex) package Chapter5;


3) 메서드
메서드는 함수의 한 종류.
-> 함수: 하나의 기능을 수행하는 일련의 코드로, 어떤 기능을 수행하도록 미리 구현해 놓고 필요에 따라 호출해 사용할 수 있음.

(더하기 함수: add 함수)
num1, num2(더할 수) 입력 -> result = num1 + num2 -> result(결과) 출력(결과 반환)
-> (코드로 옮기면)
int add (int num1, int num2) { // 좌측부터 함수 반환형, 함수 이름, (매개변수) * 반환값이 없을 때는 반환형 위치에 void를 사용.
int result;
result = num1+ num2;
return result; // return 예약어: 함수의 결괏값을 반환, 혹은 함수 수행을 종료할 때 사용하기도 함.
} // 교재(이지스퍼블리싱, 2025)의 내용을 개인 학습용으로 정리.

함수 호출과 스택 매모리
스택: 함수를 호출할 떄 그 함수만을 위해 할당되는 메모리 공간
-> 스택은 LIFO(마지막에 넣은 자료가 먼저 빠짐) 구조

함수를 호출 및 수행 후 메모리 공간이 해체되는 과정
- main() 함수가 사용될 메모리 공간이 스택에 생성됨
- main() 함수에서 사용할 함수 호출
- 호출된 함수가 사용할 메모리 공간이 스택에 생성됨
- 함수 수행 후 메모리 공간은 자동으로 사라짐
- 메모리 해제 후 main() 함수로 복귀

함수의 장점: 기능을 나누어 코드를 효율적으로 구현, 기능별로 함수를 구현해 해당 코드를 중복해서 쓰지 않아도 됨, 오류 잡는 디버깅 작업에도 편리(오류가 난 기능이 있는 함수만 찾으면 되니까)

* 하나의 함수에는 하나의 기능 구현!

메서드: 자바에서, 클래스 내부에서 멤버 변수를 사용해 클래스 기능을 구현한 함수 -> 함수에 객체 지향 개념이 포함된 용어

번외) 자바에서 이름 짓는 방법
클래스 이름 첫 글자는 대문자, 패키지 이름은 모두 소문자
카멜 표기법: ex) getStudentName, setStudentName, showStudentInfo...


4) 클래스와 인스턴스
main() 함수: 프로그램을 시작할 때 호출
main() 함수에서 클래스를 사용하는 방법
- 클래스 내부에 만들기
- 외부에 테스트용 클래스 만들어 사용

클래스 생성 코드

클래스형 변수 이름 = new 생성자;


인스턴스: 실제로 사용할 수 있도록 생성된 클래스, 클래스가 메모리 공간에 생성된 상태
참조 변수: 생성된 인스턴스를 가리키는 클래스형(참조 자료형) 변수

Student studentAhn = new Student();
/* Student 클래스형으로 studentAhn 변수를 선언하고, new Student();로 Student 클래스를 생성하여 studentAhn(참조 변수)에 대입 */

// 교재(이지스퍼블리싱, 2025)의 내용을 개인 학습용으로 정리.


* 하나의 클래스에 각각 다른 인스턴스를 여러 개 생성할 수 있음.

* 참조 변수 사용하기
참조 변수.멤버 변수 = 저장할 값
참조 변수.메서드

studentAhn.studentName = "홍길동";
System.out.println(studentAhn.getStudentName());

// 교재(이지스퍼블리싱, 2025)의 내용을 참고해 개인 학습용으로 정리.


힙 메모리: 생성된 인스턴스 안의 멤버 변수 저장에 사용되는 공간(메모리) -> 동적 메모리

 

참조 변수: 메모리에 생성된 인스턴스를 가리키는 변수 *출력 형태:  "클래스 이름@메모리 주소"
참조값: 생성된 인스턴스의 메모리 주솟값

 

5) 생성자

생성자: 클래스를 생성할 때 사용하는 함수

-> 디폴트 생성자, 프로그래머가 직접 구현하는 생성자

생성자 오버로드: 한 클래스에 생성자가 두 개 이상, 메서드 이름이 같고 매개변수만 다른 경우

 

6) 참조 자료형

참조 자료형 변수: 클래스 자료형으로 선언, 기본 자료형을 사용하듯 클래스 자료형 변수를 선언해서 사용할 수 있음

-> 참조 자료형을 사용하기 전에는 반드시 참조할 객체(클래스)를 먼저 생성해야 함.

-> 클래스를 만든 후 외부 클래스에서 (해당 클래스를 참조한) 인스턴스 변수로 선언할 수 있음.

ex) Subject 클래스를 참조한 멤버(인스턴스) 변수 korean에 대해

Subject korean; // Subject 클래스를 참조 자료형으로 한 변수 선언

korean = new Subject(); // 변수 korean의 인스턴스 생성, 생성자로 인스턴스 변수 초기화

 

7) 정보 은닉

접근 제어자: public, private, ...

get(), set() 메서드: private로 선언된 변수의 값을 호출해 대입하기 위해 사용

정보 은닉(객체 지향 프로그래밍에서): 클래스 내부에서 사용할 변수나 메서드를 private으로 선언해 외부에서 접근하지 못하도록 하는 것.

 

8) 캡슐화

캡슐화: 어떤 기능을 수행하는 데 필요한 정보를 한 곳에 모아두고 사용자에게 필요한 기능만 공개, 객체 정보가 외부로 나가지 않고 사용할 때 오류가 발생하지 않도록 함.


<6장: 클래스와 객체 2>

1) this 예약어 활용

this 예약어

-> 자신의 메모리를 가리키거나

생성자에서 다른 생성자를 호출하거나(여러 생성자가 오버로드 되었을 경우)

자신의 주소를 반환하거나

객체 자신의 인스턴스를 반환하는데

사용할 수 있다.

 

* 빌더(Builder) 패턴: (특히 생성자나 매개변수가 많은) 객체를 생성할 때 복잡함을 줄이기 위해 사용하는 디자인 패턴

this 예약어를 사용해 인스턴스 자신을 반환해 좀 더 유연하게 객체를 생성하기 위한 방법.

 

- (정보처리기사 빈출) GoF 디자인 패턴 중 '생성' 패턴에 포함.

* 개인 참고용으로 적어두는 디자인 패턴의 유형과 종류(정말 의식의 흐름이다!)
생성 패턴: 싱글턴, 팩토리 메서드, 빌더, 프로토타입, 앱스트랙트(추상) 팩토리
구조 패턴: 브리지, 플라이웨이트, 퍼사드, 프록시, 어댑터, 데코레이션, 컴포지트
행위 패턴: 전략, 옵서버, 중재자, 방문자, 이터레이터, 상태, 인터프리터, 메멘토, 커맨드, 책임 연쇄, 템플릿 메서드

 

2) 객체 간 협력

객체 지향 프로그램은 객체를 정의하고 객체 간 협력으로 만든 것.

ex) 학생이 버스나 지하철을 타고 학교에 가는 과정 -> '학생', '버스', '지하철' 세 객체를 만들어 이들을 협력시킴.

-> 세 객체는 서로 필요한 값을 주고받고 메서드를 호출하며 프로그램을 구동함.

-> 이렇게 세 객체는 서로 협력한다!

* 각 객체의 입장에서 서로 다르게 표현될 수 있는 하나의 사건이 각각의 메서드로 구현되기도 한다.

ex) '학생이 지하철을 탄다'

학생 객체 -> '학생이 지하철을 탄다' -> 학생이 지하철을 탔을 때, 가진 돈에서 요금을 차감하는 메서드

지하철 객체 -> '지하철에 학생이 탄다'-> 지하철에 학생이 탔을 때, 수입을 증가시키는 메서드

 

* 자바 프로그래밍(객체 지향 프로그래밍)을 할 때, 각 객체가 서로 영향을 주고 받는다는 점을 이해하고,

코딩 중간에도 '이 클래스는 어느 객체로부터 영향을 받는지, 이 클래스를 사용하면 다른 클래스에 어떤 영향을 줄까' 등을

꾸준히 생각하며 복기하는 습관을 들이면 학습에 더 도움이 되지 않을까?

 

3) static 변수

static 변수(또는 정적 변수 클래스 변수): 프로그램 실행 시 하나의 클래스에 속해 딱 한 번만 메모리 공간 할당

-> 모든 인스턴스가 static 변숫값 공유

-> 인스턴스 생성과 별개로 인스턴스보다 먼저 생성

-> 인스턴스가 아닌 클래스 이름으로 참조하여 사용할 수 있기에 '클래스 변수'라고도 함.

 

4) 변수의 유효 범위(상기 학습 자료 203쪽 참고해 정리)

유형 선언 위치 사용 범위 메모리 생성 및 소멸
지역(로컬) 변수 함수 내부 함수 내부에서만 스택 함수 호출될 때 생성
함수 끝나면 소멸
멤버(인스턴스) 클래스 멤버 변수로 클래스 내부
private 접근 제어자를 사용하지 않으면 다른 클래스에서도 참조 변수로 사용 가능
힙(동적) 인스턴스 생성될 때 힙에 생성
가비지 컬렉터가 수거하면서 소멸
static(클래스)
* 정적 변수 또는 클래스 변수
static 예약어 사용, 클래스 내부 클래스 내부
private 사용하지 않으면 다른 클래스에서도 클래스 이름으로 사용 가능
데이터 영역 프로그램 처음 시작 -> 상수와 함께 데이터 영역에 생성
메모리 해제할 때 소멸

 

 

5) 싱글톤(static 응용)

싱글톤 패턴: 객체 지향 프로그램에서 인스턴스를 단 하나만 생성하는 디자인 패턴

-> (정보처리기사 학습 참고) '생성 패턴'의 하나로, 하나의 객체만 선언하고, 어디서든 참조할 수 있음! 특정 클래스의 인스턴스는 오직 하나!

( 정보처리기사 실기를 위한 디자인 패턴 암기 방법 | 정처기 감자 참고해 정리, 알기 쉬운 정리 감사합니다 정처기 감자님!)

* 교재의 예제를 따라가며, static을 사용해 Company 클래스에 유일한 인스턴스를 생성해 싱글톤 패턴을 구현해볼 수 있었다!


<7장: 배열과 ArrayList>

수많은 변수를 저장하기 위해 귀찮게 하나하나 변수를 쓸 것인가?

-> 이를 해결하고자 사용하는 자료구조가 바로 '배열(array)'!

 

1) 배열

배열 선언: 자료형[ ] 배열 이름 = new 자료형[N]; // 해당 자료형 요소가 N개인 배열 선언

배열 선언과 동시에 특정 값으로 초기화: 자료형[ ] 배열 이름 = new 자료형[// 개수 쓰지마] {값1, 값2, 값3, ...}

// 개수를 쓰면 오류 발생

-> new 예약어 다음 '자료형[ ]'은 생략 가능

배열 사용

-> 배열 이름[0] = N; // 배열의 첫 번째 요소(0)에 N 값을 저장

-> 변수명 = 배열 이름[3]; // 선언한 변수에 배열의 4번째 요소(3)를 저장

* [ ]: 배열을 처음 선언할 때 사용하는 인덱스 연산자

* 배열 순서는 0번부터 시작 ex) 처음에 선언한 배열 요소 개수(배열 길이)가 6개면, 배열 순서는 0~5(=6-1)

 

배열 복사

1. for문 사용

(예시: 학습 자료에서 공부한 내용을 활용해 직접 작성)

package Array;
// 배열 복사하기 1: for문 사용
public class ArrayCopy {
    public static void main() {
        int[] array1 = new int[3];
        int[] array2 = new int[5];
        int size = 0; // 1번 배열에서 유효한 값이 저장되는 배열 길이

        array1[0] = 1; size++;
        array1[1] = 2; size++;
        array1[2] = 3; size++;

        // 2번 배열에 1번 배열의 요솟값을 복사하는 반복문
        for (int i = 0; i < size; i++) {
            array2[i] = array1[i];
        }

        // 1번 배열에서 유효한 값이 저장된 배열 길이만큼만 출력
        for (int i = 0; i < size; i++) {
            System.out.println(array1[i]);
        }

        System.out.println( ); // 출력시 한 칸 개행

        // 2번 배열의 모든 요솟값 출력(빈칸 포함)
        for (int i = 0; i < array2.length; i++) {
            System.out.println(array2[i]);
        }

    }

}

(출력 결과)

1
2
3

1
2
3
0
0

 

2. System.arraycopy() 메서드 사용

System.arraycopy(복사할 배열, 복사할 첫 위치, 붙여 넣을 배열, 붙여 넣을 첫 위치, 복사할 요소는 몇 개?)

 

다차원 배열: 다수의 행과 열과 구성된, 즉 이차원 이상으로 구현된 배열

cf) 일차원 배열: 행 하나로 이루어진 배열

 

이차원 배열 선언: 자료형[ ][ ] 배열 이름 = new 자료형[행 개수][열 개수]

(구조 예시)

arr[0][0] arr[1][0] arr[2][0]
1 3 5
7 9 0
arr[1][0] arr[1][1] arr[2][1]

 

2) 객체 배열

기본 원리는 일반 배열과 비슷함.

(다른 점)

- 객체 배열은 참조 자료형으로 선언

-> (선언 코드) 클래스형(참조 자료형)[ ] 배열 이름 = new 클래스형[배열 길이];

-> 객체 배열을 생성하는 건, 인스턴스 자체가 아닌 인스턴스를 가리키는 주솟값을 담을 공간을 만드는 것

따라서 (인스턴스) 값을 대입하지 않고 처음 출력하면 각 공간은 'null(비어 있음)'으로 출력됨.

 

- 객체 배열 복사

얕은 복사: 인스턴스 자체가 아닌 기존 인스턴스의 주솟값만 복사.

-> 각 배열(복사할 배열, 붙여넣을 배열)의 서로 다른 요소가 같은 인스턴스를 가리킴.

-> 복사할 배열의 요솟값을 바꾸면 다른 배열도 그 영향을 받아 출력값이 바뀜. 

깊은 복사: 복사할 배열에 인스턴스를 따로 생성한 후 요솟값 복사.

-> 각 배열 요소가 서로 다른 인스턴스를 가리키므로 복사할 배열의 요솟값을 바꿔도 다른 배열에는 영향 없음.

 

3) ArrayList 클래스

* 향상된 for문

for (자료형 변수명 : 요소를 대입할 배열) {
	반복 실행문
}

 

정해진 길이의 배열을 사용하며, 수정이 필요할 때마다 그때그때 코드를 다시 작성할 건가?

-> 이를 해결하고자 사용하는 객체 배열 클래스가 바로 ArrayList 클래스!

 

ArrayList 클래스의 주요 메서드(실습에서 직접 사용해 본 것): add(요소 하나를 배열에 추가), size(배열 요소 전체 개수), get(배열의 특정 위치에 있는 요솟값 반환) 등

 

ArrayList 선언 : ArrayList<자료형> 배열 이름 = new ArrayList<자료형>( );

* ArrayList를 사용할 때는 먼저 java.util 패키지를 프로그램으로 가져와야 함(import java.util.ArrayList;)

새롭게 배운 점

1) 각 항목(참조 자료형, 정보 은닉, 캡슐화 등)마다 만들고자 하는 프로그램의 종류와 성격이 다르므로

각각 별도의 패키지를 만들어 실습하면 더 효율적일 것 같다.

-> 멋모르고 챕터의 모든 내용을 하나의 패키지로 실습했다가

변수가 꼬여서 아예 모두 실행이 안 되는 오류가 발생함...(학생 성적 프로그램)

왜 저자가 예제 코드에서 항목마다 패키지명이 다르게 정의했는지 어렴풋이 깨달았다.

 

2) 이건 실습 코딩 중 사소한 실순데

각 메서드나 클래스 영역마다 블록만 꼼꼼히 묶어줘도 꽤 많은 오류를 해결할 수 있었다!

코드에 특별히 오탈자가 없는데도 오류가 난다면,

'혹시 누락된 블록(중괄호)이 없을까'하고 찾아서 고치면 대부분 잘 해결되기도 했다.

 

3) 배열과 ArrayList를 배우고 실습하면서 작지만 점점 하나의 완성된 프로그램을 만드는 경험을 할 수 있었다.

예제를 좀 더 연습한 뒤 나만의 코드로 조금씩 변경해 프로그램을 하나 만들 수 있겠다는 자신감도 생겼다!

배열을 활용할 수 있는 간단한 프로그램에는 뭐가 있을지 틈틈이 생각해 봐야겠다.

 

4) 위에도 적었지만, 

자바 프로그래밍(객체 지향 프로그래밍)을 할 때, 각 객체가 서로 영향을 주고 받는다는 점을 이해하고,

코딩 중간에도 '이 클래스는 어느 객체로부터 영향을 받는지, 이 클래스를 사용하면 다른 클래스에 어떤 영향을 줄까' 등을

꾸준히 생각하며 복기하는 습관을 들이면 학습에 더 도움이 되지 않을까?

 

실습 코드(작성자 깃허브)

https://github.com/KimGyeonkang/DoitJava_Studying_2026

 

GitHub - KimGyeonkang/DoitJava_Studying_2026

Contribute to KimGyeonkang/DoitJava_Studying_2026 development by creating an account on GitHub.

github.com

 

여담

 

이건 개인 학습용. git bash로 commit을 push하는 과정을 계속 까 먹어서 스크린샷 남겨둠