Java

[커널아카데미] 백엔드 12기 2주차 - 자바의 정석 CH06.객체지향프로그래밍1

OptimizerStart 2025. 4. 6. 19:08

1. 객체지향언어

정의

기본 프로그래밍 언어에 규칙을 추가한 것

 

규칙 종류 - 4

1) 캡슐화

2) 상속

3) 추상화

4) 다형성

 

프로그램

앞으로 컴퓨터에서 실행될 명령문 집합

 

프로그래밍

프로그램을 만드는 것

 

목적

변경에 유리

 

방법

1) 그룹화(분리)

단일 책임 (1 책임)

ex. 메서드는 한가지 일만 한다.

변하지 않는 것 / 변하는 것

- 성격이 다른 것은 분리한다.

중복된 것

- 코드와 데이터 중복은 메서드를 통해 제거

2) 관계

 

그룹화의 목적

관련있는 그룹을 묶어서 더 복잡한 것들을 처리하기 위함

역사

  • C언어는 하드웨어와 소프트웨어가 동시에 발전하여 하드웨어를 변경하는 것에 어려움이 있었음.
  • 객체지향프로그래밍( OOP)는 목표는 하드웨어에 독립적으로 변경에 유리하게 만들고자 탄생이 되었음.
    • 코드 변경에 유리하고자 캡슐화, 상속, 추상화, 다형성을 적용함.

 

 

2. 클래스와 객체

클래스

정의

1) 객체를 생성하기 위한 설계도

2) 데이터와 기능의 결합

- 관련된 변수와 메서드를 묶은 것

3) 사용자 정의 타입

- 사용자가 무한대로 생성할 수 있음 

 

설계 

서로 관련된 속성과 기능을 뽑아내는 것이 관찰과 분석을 통해 이뤄지고, class 에 작성할 때 설계 및 구현이 됨.

 

객체

정의

[프로그래밍 관점] 클래스에 정의된 내용대로 메모리에 생성된 것 

[개념] 실제로 존재하는 사물 혹은 개념. 상품

 

구성

1) 속성

2) 기능

 

객체를 사용

객체의 속성과 기능을 사용하는 것

 

3. 변수와 메서드

변수

정의

1. 저장 공간

2. Read 계산한 값을 읽기

3. Write 계산한 값을 저장공간에 쓰기

코드 안에서의 영역

 

변수 종류 존재하는 영역  생성 시기
클래스 변수  클래스 영역 클래스가 메모리에 로딩 될 때
인스턴스 변수  클래스 영역 인스턴스가 생성될 때
지역변수  메서드 영역, 생성자 내부, 초기화 블록 내부  메서드 내에 선언문이 실행될 때

 

특징

 

클래스 변수

  • 인스턴스를 생성하지 않고 '클래스명.클래스변수명'을 통해 사용 가능. '참조변수명.클래스변수명'도 가능. 
  • 동일한 클래스를 통해 생성된 인스턴스들이 공유하는 저장공간. 인스턴스들이 동일한 값을 유지해야하는 속성일 때 사용.
  • 클래스 영역에 선언됨.
  • static 메서드 내부에서 사용가능. 인스턴스 메서드 내부에서 사용 불가. 
  • 객체를 생성하면 인스턴스 변수 사용 가능
java
닫기
static int cv = new MemberCall().iv;

 

 

인스턴스 변수

  • 인스턴스 생성 후 '참조변수.인스턴스변수명'을 통해 사용가능. 인스턴스 생성 없이 접근 불가
  • 인스턴스를 생성될 때마다 인스턴스마다 각각 다르게 값을 설정할 수 있음. 인스턴스마다 독립적인 메모리 공간을 할당 받기 때문.
  • 클래스 영역에 선언됨

 

 

지역변수 

  • for문, while문, 초기화 블록, 메서드(생성자 포함) 내부에 선언한 변수. 매개변수 포함 
  • {} 블록 바깥에서는 접근 불가 

 

 

 

메서드

정의

  • 작업에 필요한 관련된 문장 묶음
  • 명령문 집합

 

작성 방법

객체지향에서의 함수. 클래스안에 작성해야함.

 

목적

1. 코드 재사용성 

2. 중복 코드 제거 

3. 프로그램 구조화 = 설계 방식

- main 메서드 내에서 전체적인 실행 흐름을 파악하기 위해,

1) 주석으로 기능을 작성, 2) 구현부 없는 메서드를 작성 한 뒤, 3) 하나씩 메서드 내부를 완성해 나간다. 

 

구성

1. 선언부

반환타입 메서드명 (매개변수 타입 매개변수명, 매개변수 타입 매개변수명, ...) 

 

2. 구현부

  • {} 블록 안에 작성됨.
  •  void 반환타입이 아닌경우, 모든 경우에 return 반환값을 명시해야 함. 
  • return 문 현재 실행 중인 메서드를 종료하고 호출한 메서드로 되돌아감

 

 

종류

1. 클래스 메서드 (= static 메서드) 

  • static이 메서드 반환타입 오른쪽에 붙여있는 메서드
  • 인스턴스 생성 없이 호출할 수 있는 메서드. 인스턴스 변수(iv)를 사용하지 않는 메서드
  • 작업에 필요한 입력값을 매개변수를 통해 입력 받아야함. 변경 시 수정할 부분이 인스턴스 메서드보다 상대적으로 많이 생김. 
    • 메서드 선언부가 수정되면 해당 메서드를 호출하는 부분까지 수정해야하기 때문.
  • 인스턴스 메서드는 참조변수로 객체의 메서드를 찾아야하는 과정이 추가되므로, 메서드 호출 시간이 짧아짐
  • 변경 불리. 성능 빠름. 

 

2. 인스턴스 메서드 

  • 인스턴스가 필요한 메서드. 객체 생성을 하고 참조변수를 통해 호출할 수 있는 메서드
  • static 메서드, static 변수를 인스턴스 메서드 내부에서 사용할 수 있음. 
  • 작업에 필요한 입력 값을 인스턴스 변수에 저장하여 매개변수 개수를 줄일 수 있음. 선언부가 수정되지 않아 변경 사항 적음.
  • 변경 유리. 객체 생성 후 인스턴스 접근이 가능하므로 클래스 메서드보다 성능 느림.

 

인스턴스 메서드가 되면 좋은 점

매개변수 감소

매개변수 개수가 줄고 변경에 유리함

static 메서드, 인스턴스 메서드의 차이점

  • static 메서드 인스턴스 변경 시 매개변수 목록 변경해야함
  • 인스턴스 메서드 iv와 관계 있어 매개변수 작성 안해도 됨
java
닫기
package CH06_OOP1; class MyMath2 { ​​​​// 인스턴스 메서드. 호출 시 매개변수 목록 없음. ​​​​long x, y; ​​​​long add() { return x + y;} // 인스턴스 변수 이용 ​​​​long subtract(){ return x - y;} ​​​​long multiply() { return x * y;} ​​​​double divide() { return x / y; } ​​​​// 클래스 메서드. 호출 시 매개변수 목록 고정 ​​​​static long add (long x, long y) { ​​​​​​​​return x + y; ​​​​} ​​​​static long subtract(long x, long y) { ​​​​​​​​return x - y; ​​​​} ​​​​static long multiply(long x, long y) { ​​​​​​​​return x * y; ​​​​} ​​​​static double divide(double x, double y ){ ​​​​​​​​return x / y; // 매개변수를 double로 지정하면 return 에서 명시적 형변환을 하지 않아도 됨. ​​​​} } public class MyMathTest2 { ​​​​public static void main(String[] args) { ​​​​​​​​// 클래스 메서드, 인스턴스 메서드 차이 이해 ​​​​​​​​// 클래스 메서드 호출. 인스턴스 생성 없이 호출 가능 ​​​​​​​​System.out.println(MyMath2.add(200L, 100L)); ​​​​​​​​System.out.println(MyMath2.subtract(200L, 100L)); ​​​​​​​​System.out.println(MyMath2.multiply(200L, 100L)); ​​​​​​​​System.out.println(MyMath2.divide(200.0, 100.0)); // 인자줄 때 double로 주면 됨. ​​​​​​​​MyMath2 mm = new MyMath2(); // 인스턴스 생성 ​​​​​​​​mm.x = 200L; // 인스턴스 변수 접근해서 값을 줌. 매개변수로 주는게 아니라 ​​​​​​​​mm.y = 100L; ​​​​​​​​System.out.println(mm.add()); ​​​​​​​​System.out.println(mm.subtract()); ​​​​​​​​System.out.println(mm.multiply()); ​​​​​​​​System.out.println(mm.divide()); ​​​​} }

 

차이점 

인스턴스 변수 사용 여부 

  • 클래스 메서드는 인스턴스 변수 사용 X
  • 인스턴스 메서드는 인스턴스 변수 사용 O

 

4. 메서드 오버로딩 Overloading

정의

같은 클래스 내의 이름이 같은 메서드를 여러 개 정의해 놓은 것 

java
닫기
void println(int x) void println(boolean b) void println(float x) ..

조건

1. 메서드 이름이 같아야 함.

2. 매개변수 개수 또는 타입이 달라야 함.

3. 반환 타입은 오버로딩에 영향 주지 않음.

  •  반환 타입이 다르고 매개변수 개수 또는 타입이 같으면 오버로딩이 아님. 

 

메서드와 메서드 이름 관계

 

메서드와 메서드 이름 관계

메서드는 동사로 이름이 지어진다. 동사의 의미는 동일한데, 어떻게 내용을 처리할지는 어떤 입력 값을 받고 처리하는지에 따라 선언부와 구현부가 달라진다. 예를 들어 add()의 경우 '더하기'하는 기능은 동일하지만, 어떻게 입력을 받고 처리할지에 따라 메서드 선언부가 달라진다. 입력값 2개를 받는 경우와 입력값 2개와 계산 결과를 저장하는 변수를 포함해 매개변수가 3개인 함수를 오버로딩한다 해보자. 사용자는 원하는 형태에 따라 오버로딩이 없다면 메서드 이름으로 형태가 다른 것을 나타내야한다. 같은 기능임에도 다르게 메서드를 호출해야하는 불편함이 존재한다. 사용자 편의성을 위해 오버로딩을 사용한다.

java
닫기
int add (int x, int y ) { return a + b; } int add (int x, int y, int result) { ‌result = x + y; return result; }

 

 

5. 생성자 Constructor

정의

인스턴스 변수를 초기화 하는 메서드

 

조건

1. 생성자 이름은 클래스 이름과 같아야 함

2. 반환 값이 없음

3. 다른 생성자 호출 시 생성자 구현부 맨 첫줄에 작성해야 함

 

규칙

모든 클래스에는 반드시 1개 이상의 생성자가 있어야함.

 

종류

1. 기본생성자

 

정의

  • 매개변수가 없는 생성자

특징

  • 클래스 안에 생성자를 작성하지 않으면, 컴파일러가 자동으로 기본 생성자를 삽입
  • 클래스 안에 생성자를 하나라도 작성하면, 컴파일러가 자동으로 기본 생성자를 삽입 하지 않음. 클래스 작성 시 항상 기본 생성자를 넣은 습관 중요.

2. 매개변수가 있는 생성자 

객체 생성과 동시에 입력 값으로 인스턴스 변수 초기화 가능

java
닫기
Card c = new Card("Heart", 8); Card c = new Card(); c.kind = "Heart"; c.number = 8;

 

new 와 생성자 메서드 관계

new와 생성자의 관계

 

new를 이용해 객체를 생성하고 생성자를 통해 객체 초기화한 후에 생성된 객체가 참조변수에 저장된다. 이 과정을 자세히 살펴보자. 

new를 통해 객체를 생성하고 생성자는 객체의 인스턴스 변수를 초기화만 한다고 했다.
하지만, 생성자 내부에서는 객체의 주소를 저장하거나 전달하는 코드가 없는데,
참조변수에 어떻게 객체의 주소가 저장되나?

 

 

new가 객체를 생성하고 생성된 객체의 주소를 생성자에게 전달한다. 하지만 생성자 코드에서는 객체의 주소를 저장한 코드가 없다.

[코드1 참고]

 

[코드 1] 실제로 보는 코드

자바에서는 당연한 행동들을 생략한 것이라 볼 수 있다. 즉, new가 객체를 생성하고 생성된 객체의 주소를 생성자의 매개변수이자 참조변수인 this 에게 전달한다. this는 생성된 객체의 주소를 저장하고 있다. 그 후 구현 부에서 반환값에 this 를 주면 객체의 타입과 일치한 타입이 반환 타입이 된다. return 문에 의해 생성된 객체의 주소가 참조변수에 저장된다. [코드2] 참고

[코드2] 생략된 생성자의 반환타입, 반환값, 매개변수

 

this 참조변수

정의

인스턴스 자신을 가리키는 참조변수

 

특징

this 참조변수는 모든 인스턴스 메서드에 지역 변수로 존재함. 생략된 상태임.

java
닫기
class Car { ​​​​String color; ​​​​String gearType; ​​​​int door; ​​​​ ​​​​Car() { ‌​​​​this("white", "auto", 4); // 참조변수 this아님. this() 생성자임 ​​​​​​​​} // 매개변수에 생성된 객체의 주소 저장하고 있는 참조변수 this가 생략된 상태 ​​​​Car(String this, String color, String gearType, int door) { ‌​​​​this.color = color; ​​​​​​​​this.gearType = gearType; ​​​​​​​​this.door = door; ‌‌} ​​... }

 

this() 생성자

정의

같은 클래스 내의 생성자에서 다른 생성자를 호출

 

목적

중복 제거. 생성자도 오버로딩이 가능하며, 인스턴스 변수 값을 초기화하는 것이 목적이기 때문에 초기화 코드가 중복되는 것을 방지하기 위해 사용

 

특징

다른 생성자 호출은 생성자 첫문장에서만 가능

 

6. 변수의 초기화

정의

변수를 선언하고 처음으로 값을 저장하는 것

 

특징

  • 자동 초기화는 각 타입의 기본 값으로 저장
  • 지역 변수는 수동 초기화 해야하고 클래스 변수, 인스턴스 변수는 자동 초기화 됨
    • JVM의 Call Stack은 재사용이 빈번한 메모리이기 때문에 아주 짧은 시간동안여러 메서드가 같은 공간을 사용한다. 메서드가 호출될 때마다 메모리 공간을 초기화하면 성능이 떨어지므로 수동 초기화로 값을 덮어쓰는 방식을 채택했다. 

종류

1. 명시적 초기화 (= 간단 초기화)

  • 대입 연산자 이용

2. 생성자 (= 복잡 초기화)

  • 여러 문장으로 초기화를 하기 때문에 복잡 초기화라한다.

3. 초기화 블럭 (= 복잡 초기화)

  • static{} 클래스 변수를 초기화 
  • {} 인스턴스 변수 초기화 

 

실행 순서

1. 클래스 변수 초기화 -> 인스턴스 변수 초기화

2. 자동 초기화 (기본값) -> 간단 초기화(대입연산자) -> 복잡 초기화(static{}, 생성자)

 

 

2주차 회고

 

# 빈틈을 확인

자바의 정석 ch02~05의 연습 문제를 풀기 전에 빨리 풀 수 있겠다는 생각을 가지고 있었다. 하지만 실제로 풀어보니 내가 제대로 알지 못하는 부분을 찾을 수 있었다. 특히 타입과 연산자 부분이 약했다. shift 연산은 write를 하지 않는 연산자이고, 단항 연산자(++)와 이항연산자의 +는 어셈블리 단에서 INC와 ADD로 변환되어 형변환 여부가 다르다는 것을 배웠다. 

 

# 생각과 말하는 것의 간극 확인

강사님께서 기본형 변수, 참조형 변수, 참조변 반환 타입을 가진 코드를 실행할 때 콜 스택의 진행과정을 중요하게 여기셔서 실제로 콜스택과 힙 영역의 생성 주기를 그림으로 그리면서 말로 설명하는 과제를 내주셨다. 강의실에선 조용히 해야해서 머릿속으로 생각하면서 그림을 그릴 땐 금방 끝낼 수 있겠다고 여겼다. 집에 와서 영상을 찍으니 절대 한두번에 되지 않았다. 영상만 한 예제당 기본 7번 정도는 찍었다. 여러 번 반복할 때마다 수정을 조금씩 하니 거의 8번 9번 찍을 때는 말이 술술 나왔다. 반복이 중요하고 내가 말하는 것도 중요함을 체감했다.