1. 오늘 학습 키워드 : 계산기 과제 2단계, Java 특강
2. 학습 내용을 나만의 언어로 정리
Java는 클래스로 이루어진 객체지향 프로그래밍 언어이다.
클래스는 속성, 생성자, 기능 으로 이루어짐 ( 속생기 )
3. 학습내용
14:00 ~ 15:00 프로그래밍 기초 특강 ( 박성원 튜터님, 클래스란 무엇인가? )
🌟AI 설정 끄기🌟 - 편하긴하나, 의존하게 되면 나중에 그 의미를 알지도 못한채 사용할 가능성이 있는거 같음.
| 접근 제어자 | 같은 클래스 | 같은 패키지 | 상속한 클래스 | 다른 패키지 |
| public | ✅ | ✅ | ✅ | ✅ |
| protected | ✅ | ✅ | ✅ | ❌ |
| default (직접선언 x) | ✅ | ✅ | ❌ | ❌ |
| private | ✅ | ❌ | ❌ | ❌ |
객체지향 프로그래밍(OOP)란?
- OOP(Object-Oriented Programming) = " 객체를 중심으로 프로그램을 설계하는 방식 "
- 현실 세계의 사물을 코드로 표현해 재사용성, 유지보수성, 확장성을 높임
예시 : 자동차
class Car {
// 속성
String brand; // 브랜드
String color; // 색상
int speed; // 속도
// 기능
void start() {
System.out.println(brand + " 자동차가 출발합니다.");
}
void stop() {
System.out.println(brand + " 자동차가 멈춥니다.");
}
void accelerate(int amount) {
speed += amount;
System.out.println(brand + " 자동차의 현재 속도: " + speed + "km/h");
}
}
패키지란?
- 패키지(package)는 관련 있는 클래스들을 논리적으로 그룹화하는 방법이다.
- 패키지를 사용하면 코드 관리가 편리하고, 클래스 이름 충돌을 방지할 수 있다.
- 패키지는 폴더(디렉토리) 형태로 구성되며, 실제 파일 시스템에서도 동일하게 나타난다.
- 프로젝트내 package (경로); 로 설정 되어 있는것이 현재 내가 보고있는 패키지이다. ( 코드 맨위에 있음 )
객체 지향 프로그래밍의 4대원칙
1. 캡슐화
- 객체의 속성과 메서드를 하나로 묶고, 외부에서 직접 접근하지 못하도록 데이터 보호하는 것
- private 키워드를 사용해 필드를 보호함.
2. 상속
- 기존 클래스의 기능을 그대로 가져와 확장하는 것 ( 코드 재사용 )
- 부모 클래스(상위 클래스)의 기능을 자식 클래스(하위 클래스)가 물려받아 사용 가능
※ 자식 생성자를 생성하려면, 부모의 생성자가 무조건 있어야 한다. super();
→ 단, 부모의 기본 생성자가 자동으로 생성되기 때문에, 자식 생성자는 super() 키워드 없이 생성 가능함.
3. 다형성
- 같은 메서드를 여러 클래스에서 다르게 동작하게 만드는 기능
※ 메소드 오버라이딩 ( 재정의 )
부모가 가지고있는 메소드를 자식클래스에서 똑같은 메소드명으로 선언하고, 구현체를 다시 해당 자식 클래스에 맞게 구현하는 것으 말한다.
4. 추상화
- 필요한 정보만 제공하고, 불필요한 세부 사항은 숨기는 것
- 핵심 기능만 보여주고, 내부 구현을 감출 수 있음.
- abstract 키워드를 사용하여 추상 클래스를 만듬. 추상 클래스는 구현체가 없다. ( 추상적인 내용은 해당 클래스에 상속 하고, 구현을 함 )
객체지향적인 클래스 설계방법
- 클래스는 "하나의 역할"만 하도록 설계
- 중복 코드를 줄이고, 필요하면 상속을 활용
- 공통된 기능은 부모 클래스로 관리
- 필요한 정보는 private로 숨기고, public 메소드를 제공
- 같은 동작을 다양하게 구현할 수 있도록 다형성을 활용
- 추상화를 통해 핵심 기능만 드러내고, 불필요한 세부 사항을 감추기
객체와 인스턴스
클래스
- 클래스는 객체를 만들기 위한 설계도 또는 틀
- 클래스는 객체가 가져야 할 속성(변수)과 기능(메서드)을 정의한다. ( 생성자도 있음 )
객체
- 객체는 클래스의 설계도를 바탕으로 만들어진 구체적인 대상
- 객체는 실제 메모리상에서 존재
- ex) 실제로 만들어진 쿠키 : 초콜릿 쿠기, 딸기 쿠기
Cookie chocolateCookie = new Cookie();
chocolateCookie.flavor = "초콜릿";
chocolateCookie.size = 5;
chocolateCookie.bake(); // "초콜릿맛 쿠키를 굽습니다."
인스턴스
- 특정 클래스로부터 생성된 개별 객체를 가리킬 때 사용되는 표현
Cookie strawberryCookie = new Cookie(); // Cookie 클래스의 인스턴스
strawberryCookie.flavor = "딸기";
strawberryCookie.size = 3;
strawberryCookie.bake(); // "딸기맛 쿠키를 굽습니다."
| 용어 | 설명 | 예시 |
| 클래스(Class) | 객체를 생성하기 위한 툴 | 쿠키 툴(설계도) |
| 객체(Object) | 실제 존재하는 구체적 대상 | 실제 쿠키 |
| 인스턴스(Instance) | 클래스에서 맏늘어진 구체적 객체 | 초콜릿 쿠키(쿠키 틀의 인스턴스) |
클래스는 객체를 생성하기 위한 툴이다. 실제로 존재하지 않고, 설계도 역할
객체는 클래스에 정의된 속성과 메소드를 가진 실제 구체적인 존재
인스턴스는 클래스로부터 객체가 생성된 순간, 그 특정 객체를 명확하게 가리키는 용어
객체를 만들 때 new 키워드를 사용하며, 이렇게 만들어진 객체를 인스턴스화
- 캡슐화 : 데이터 보호
- 상속 : 코드 재사용
- 다형성 : 같은 메서드를 여러 형태로 사용
- 추상화 : 중요한 기능만 노출하고, 세부 구현은 숨김
■ 계산기 과제 2단계 ■
| 클래스를 적용해 기본적인 연산을 수행할수 있는 계산기 만들기 |
package com.example.calculator;
import java.util.Scanner;
public class App {
public static void main(String[] args) {
// 2단계 클래스를 적용해 기본적인 연산을 수행할 수 있는 계산기 만들기
Scanner sc = new Scanner(System.in);
Calculator calculator = new Calculator();
while(true) {
System.out.print("첫번째 정수를 입력하세요: ");
int num1 = sc.nextInt();
if (num1 < 0) {
System.out.println("음수는 입력할수 없습니다.");
continue;
}
System.out.print("두번째 정수를 입력하세요: ");
int num2 = sc.nextInt();
if (num2 < 0) {
System.out.println("음수는 입력할수 없습니다.");
continue;
}
System.out.print("사칙연산(+, -, x, /) 기호를 입력하세요: ");
char op = sc.next().charAt(0); // 문자열에서 첫 번째 문자만 추출
int result = calculator.calculate(num1, num2, op);
System.out.println("결과 = " + result);
sc.nextLine(); // 버퍼 지우기
System.out.print("더 계산하시겠습니까? (exit 입력 시 종료): ");
String answer = sc.nextLine();
if (answer.equals("exit")){
System.out.println("계산기 시스템을 종료합니다.");
System.out.println("최종연산 결과 기록 : " + calculator.getRecord());
break;
}
System.out.print("먼저 저장된 연산 결과 기록을 삭제 하겠습니까? (0 입력시 삭제): ");
String delete = sc.nextLine();
if (delete.equals("0")) {
calculator.removeResult();
System.out.println("가장 먼저 들어온 연산 결과가 삭제 되었습니다.");
}
// 저장된 연산 결과값 매회 조회.
System.out.println(calculator.getRecord());
}
}
}
Main 클래스
package com.example.calculator;
import java.util.ArrayList;
import java.util.List;
public class Calculator {
private List<Integer> record = new ArrayList<>();
public int calculate(int num1, int num2, char op) {
int result = 0;
switch (op) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2 == 0) {
throw new ArithmeticException("나눗셈 연산에서 분모에 0이 입력될 수 없습니다.");
} else {
result = num1 / num2;
break;
}
default:
throw new RuntimeException("부호를 잘못 입력하였습니다");
}
record.add(result); // 연산 결과 기록 추가함.
return result;
}
public void removeResult() {
if(!record.isEmpty()) {
record.remove(0); // 가장 먼저 저장된 값을 삭제함.
} else {
System.out.println("연산 결과가 기록되어 있지 않습니다.");
}
}
public void setRecord(List<Integer> record) {
this.record = record;
}
public List<Integer> getRecord() {
return record;
}
}
Calculator 클래스
[트러블 슈팅]
- 배경 : 2단계는 클래스를 활용해, 코드의 재사용성을 줄이고, 효율적인 코드를 만들기 위해 코드를 분리 하여야 한다.
- 발단 : Calculator 클래스를 만들고 사칙연산 기능을 메서드화하는 과정에서 어떤 부분을 분리할지 고민이 필요했다.
- 연산 기능 calculate()
- 연산 결과 저장 record 리스트
- 결과 삭제 기능 [ 먼저들어온 데이터부터 삭제 ] removeResult()
- 전개 :먼저, Calculator 클래스에서 연산을 수행하는 calculate() 메서드를 만들고,결과를 저장하는 record 리스트를 추가했다. 이후, removeResult() 메서드를 구현하여 가장 오래된 결과를 삭제하는 기능을 추가했다. 1️⃣ record 리스트가 외부에서 직접 접근 가능하여 데이터를 조작할 수 있는 문제 발견
2️⃣ removeResult()를 호출했을 때 리스트가 비어있으면 예외 처리 부족
3️⃣ App 클래스에서 record에 직접 접근하는 코드로 인해 캡슐화 부족 ➡ 데이터 보호를 위해 캡슐화(Encapsulation) 가 필요함.
- 위기 : 클래스를 나눴음에도 불구하고,
- record 리스트가 setRecord()를 통해 외부에서 수정 가능한 상태
- removeResult() 호출 시, 리스트가 비어 있으면 오류 발생 가능
- App 클래스가 여전히 record를 직접 수정하면서 클래스를 분리한 의미가 약해짐
- 절정 : 1️⃣ record 필드를 private으로 설정하여 직접 접근 차단
2️⃣ setRecord() 제거 → 외부에서 수정 불가능하도록 변경
3️⃣ getRecord()에서 새로운 리스트를 반환하여 원본 리스트 보호
4️⃣ removeResult() 실행 시, 리스트가 비어 있으면 경고 메시지 출력 - 결말 :이제 Calculator 클래스는
- 연산 수행 calculate()
- 결과 저장 record 리스트
- 결과 삭제 removeResult()
을 책임지는 역할을 갖게 되었고,
이제 App 클래스는 Calculator 객체를 이용하여 입출력만 담당하면 된다.
최성원 튜터님의 튜터링 - 자바는 컬렉션까지는 기본이며, 제네릭, 어노테이션은 필수다!
제네릭의 <T> 타입매개변수는 제네릭의 일부분임.
람다식, 스트림 까지 알아두면 좋고 쓰레드는 당장 필요한 영역은 아니다.
git을 CLI이나 GUI로 사용하는것은 무관하다.
4. 내일 학습 할 것 : 계산기 도전과제 3단계 도전, 자바 복습
'[내일배움캠프-Sparta] > Spring 6기' 카테고리의 다른 글
| TIL 13 [ Java(동일성 문제, 클래스와 객체, charAt함수) ] (0) | 2025.03.06 |
|---|---|
| TIL 12 [계산기 과제 3단계(enum, 제네릭, 람다, 스트림)] (0) | 2025.03.05 |
| TIL 10 [ Java(람다식, 스트림, 쓰레드) + 계산기 과제 1단계 ] (0) | 2025.02.28 |
| TIL 9 [ Java(예외처리, Optional, 제네릭, 컬렉션) ] (0) | 2025.02.27 |
| TIL 8 [ Java(final, static, 인터페이스, 객체지향) ] (0) | 2025.02.26 |