목차
1. Chapter 2 - 1 : 클래스와 객체
수업 목표
● 클래스와 객체가 무엇인지 학습합니다.
● 클래스를 직접 만들어보고 객체화하는 방법을 학습합니다.
1. 클래스(Class)
- 객체를 만들 때 필요한 청사진(설계도)
- 클래스의 첫글자는 대문자여야함.
2. 객체(Object)
- 실제로 존재하는 것.
- 주변에서 볼 수 있는 사물들이 객체.
- 어떤 개념이나 논리도 객체가 될 수 있음.
- 클래스가 준비되어 있다면 클래스를 기준으로 여러 객체들을 만들 수 있음.
예시)Person.class
- 객체를 만들 때 "new" 라는 키워드 사용.
- 객체를 만드는 과정을 "인스턴스화" 라고 표현함.
- 인스턴스화가 되면 Java 메모리 상에 객체가 만들어짐.
public class Person() {
...
}
public class Main {
public static void main(String[] args) {
Person personA = new Person(); // ✅ 첫번째 객체 생성
Person personB = new Person(); // ✅ 두번째 객체 생성
}
}
클래스 구조
- 클래스 구조는 1. 속성, 2. 생성자, 3. 기능 부분으로 나누어짐.
- 속생기 라고 외우기!
class 클래스 {
// 1. 속성
// 2. 생성자
// 3. 기능
}
속성(property, field)
- 객체는 속성(특징)을 작성하는 곳.
- 객체를 생성해야 속성에 접근 가능.
- 속성들은 변수로 표현함.
- 프로퍼티(property), 필드(field)라고도 함.
ex) 나이, 이름 주소 등
Person.java
public class Person {
// 1, 속성 - 변수 선언으로 표현할 수 있습니다.
String name;
int age;
String address;
// 2. 생성자
// 3. 기능
}
Main.java
public class Main {
public static void main(String[] args) {
Person personA = new Person(); // ✅ 첫번째 객체 생성
Person personB = new Person(); // ✅ 두번째 객체 생성
}
}
속성에 접근
- 객체를 통해 속성에 접근 시 객체가 담긴 변수. 속성 으로 접근.
- 객체마다 속성 값이 다를 수 있음.
public class Main {
public static void main(String[] args) {
// 1. 객체 생성
Person personA = new Person();
Person personB = new Person();
// 2. ✅ 객체를 통해 접근 personA 의 name
System.out.println(personA.name);
// 3. ✅ 객체를 통해 접근 personB 의 name
System.out.println(personB.name);
}
}
생성자
- 객체를 만들 때 사용.
- 객체를 어떻게 만들지 정의해 놓는 것.
- 생성자가 없으면 클래스를 객체화(인스턴스화) 시킬 수 없음.
기본 생성자
- 클래스 생성 시 기본 생성자는 자동으로 추가됨 → 우리 눈에 보이지 않음
Ex) Person( ) { }
- 그래서 클래스 객체화가 가능.
생성자 특징
1. 반환 자료형이 없음.
2. 클래스명과 이름이 똑같음.
3. 여러 개가 존재할 수 있음.
생성자를 활용해 Person 객체 만들기
예시)
public class Person { String name; int age; String address; Person() {} // ❌ 기본생성자 제거됨 Person(String name, int age) { // ✅ 새로운 생성자(조립설명서) this.name = name; this.age = age; } } |
- Person( ){ } → 자동으로 눈에 안보이게 생성되어 있던 생성자를 직접 입력한 것.
- 생성자 범위에서 접근할 수 있는 변수는 총 5개임(변수별 색상 참고)
- 클래스 안에 정의된 변수들은 내부(Person(String name, int age){ }) 에서도 사용 가능.
- 메서드에 설정된 변수가 없으면 this 를 안 붙여도 됨. 하지만 확실히 detecting 하기 위해서 쓰면 좋음.
(회사마다 다름)
기능(메서드)
- 객체의 기능을 나열하는 곳.
- 기능은 메서드로 표현함.
- 클래스와 관련된 기능을 작성하는 것이 좋음.
- 메서드를 활용하는 것이 객체의 기능을 활용하는 것.
게터(Getter)
- 클래스의 속성을 가져올 때 사용되는 기능.
- 속성 읽기 가능, 수정 및 삭제 불가능.
// Class.java
String getName() {
return this.name;
}
int getAge() {
return this.age;
}
String getAddress() {
return this.address;
}
//Main.java
String name = person.getName();
int age = person.getAge();
String address = person.getAddress();
세터(Setter)
- 객체의 속성을 외부에서 설정할 수 있게 해주는 기능.
- 속성 수정 및 삭제 가능.
// Class.java
void getName(String name) {
this.name = name;
}
void getAge(int age) {
this.age = age;
}
void setAddress(String address) {
this.address = address;
}
// Main.java
public class Main {
public static void main(String[] args) {
Person personA = new Person("gygim", 20);
Person personB = new Person("Steve", 15);
personA.setAddress("서울"); // ✅ personA 의 주소 설정
personB.setAddress("미국"); // ✅ personA 의 주소 설정
}
}
[실습 과제]
💬 Q1. 자동차 클래스를 상상해서 만들어 보고 활용해 보세요.
💡요구사항
- Car 클래스를 만든다.
- 속성 - 자동차의 속성을 저장할 변수를 만든다.
- 생성자 - 조립할 속성을 골라 객체화를 시켜주세요.
- 기능 - 다양한 기능을 만들어보고 활용해보세요.
→ drive() 주행 기능
→ accelerate() 가속 기능
Car.java
public class Car {
String name;
String model;
String color;
int speed;
Car(String name, String model){
this.name = name;
this.model = model;
}
String drive(){
return this.model + " " + this.name + "의 운전을 시작합니다.";
}
int setSpeed(int speed){
return this.speed = speed;
}
void accelerate(){
System.out.println(this.name + "의 현재 속도는 " + this.speed + " km/h 입니다." );
}
}
Main.java
public class Main {
public static void main(String[] args) {
Car car = new Car("부릉이", "람보르기니 아벤타도르");
String driving = car.drive();
System.out.println(driving);
car.setSpeed(180);
car.accelerate();
}
}
정답)
Car.java
public class Car {
// 1. 속성
String name;
String carModel;
// 2. 생성자
public Car(String name, String carModel) {
this.name = name;
this.carModel = carModel;
}
// 3. 기능
public void drive() {
System.out.println(name + "[" + this.carModel + "] 을 주행합니다.");
}
...
}
Main.java
public class Main {
public static void main(String[] args) {
// 자동차 객체 생성
Car myCar = new Car("나의자동차", "K8");
myCar.drive();
}
}
2. Chapter 2 - 2 : JVM 메모리 영역
수업 목표
● JVM 메모리 영역을 학습합니다.
JVM 메모리 구조
1. Method Area
- 프로그램이 실행되면 작성했던 모든 파일(.java)의 데이터가 Method(static) 영역에 저장됨.
- 프로그램 실행 시점에 한 번만 저장됨.
- 모든 객체가 공유하는 공용 공간 → 저장된 데이터는 프로그램 전체에서 공용으로 활용 가능.
2. Heap Area
- new 키워드로 생성된 객체는 Heap 영역에 저장됨.
- Stack 영역의 변수가 Heap 영역의 객체를 참조함.
= 객체를 담은 변수에는 실제 객체의 Heap 메모리 주소값이 저장됨.
3. Stack Area
- 메서드가 호출될 때마다 Stack 영역에 메모리가 할당됨.
- 스택프레임(= 접시 하나 )에 각 메서드의 지역변수가 저장됨.
- 접시를 쌓는 것처럼 LIFO(후입선출) 구조.
- 메서드가 시작되면 추가되고, 메서드가 종료되면 사라지는 구조.
- 특정 메서드가 실행되면 해당 메서드의 정보와 변수가 Stack에 저장되고, 메서드 실행이 끝나면 그 메모리는 자동으로 제거됨.
- 메서드 내에 선언된 "지역변수" 들이 저장되는 공간.
→ 변수에 객체가 담기면 객체의 주소값이 저장됨.
* LIFO(Last In First Out) - 후입선출
- 마지막에 들어온 요소가 제일 먼저 나가게 되는 구조.
* Garbage Collector
- Java의 사용하지 않는 객체를 자동으로 제거하는 기능.
- new 키워드로 생성한 객체는 Heap 영역에 저장됨.
- 사용이 끝난 객체는 메모리에 남아있으면 낭비.
→ 가비지 컬렉터가 이러한 불필요한 객체를 자동으로 정리해서 메모리 확보.
[퀴즈]
Q1. Method Area 는 프로그램 시작 시 한번만 클래스 정보를 저장한다.
답) Yes
Q2. Stack 영역은 메서드 호출이 끝나면 자동으로 해당 메서드의 데이터를 제거한다.
답) Yes
Q3. Heap 영역에 생성된 객체는 프로그램 종료 전까지 절대 사라지지 않는다.
답) No
❌ Heap 영역의 객체는 필요 없어지면 가비지 컬렉터(GC)가 정리 가능.
3. 계산기 과제
Lv 1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기
필수 기능 요구사항
- 양의 정수(0 포함)을 입력받기.
- Scanner를 사용하여 양의 정수 2개(0 포함)을 전달받을 수 있음.
- 양의 정수는 각각 하나씩 전달 받음.
- 양의 정수는 적합한 타입으로 선언한 변수에 저장함.
- 사칙연산 기호( +, - , × ,÷ ) 를 입력받기.
- Scanner를 사용하여 사칙연산 기호를 전달 받을 수 있음.
- 사칙연산 기호를 적합한 타입으로 선언한 변수에 저장.
- 위에서 입력받은 양의 정수 2개와 사칙연산 기호를 사용하여 연산을 진행한 후 결과값을 출력하기
- 사칙연산 기호에 맞는 연산자를 사용하여 연산 진행.
- 입력받은 연산 기호를 구분하기 위해 제어문 사용.
- 연산 오류가 발생할 경우 해당 오류에 대한 내용을 정제하여 출력.ex) "나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다."
try {
result = calculator.division();
} catch (ArithmeticException e) {
System.out.println("나눗셈 연산에서 두번째 정수에 0을 입력할 수 없습니다.");
}
이 부분은 try ~ catch 문을 사용하였다.
- 반복문을 사용하되, 반복의 종료를 알려주는 “exit” 문자열을 입력하기 전까지 무한으로 계산을 진행할 수 있도록 소스 코드를 수정하기
❗발생한 이슈
- 반복 종료를 알려주는 exit 문자열을 입력하려고 할 때, 문자열 입력이 생략되고 바로 반복문이 시작되는 문제가 있었다.
nextInt()는 Enter나 공백을 기준으로 int형 값을 가져온다. 그러면 큐에 Enter 값이 남아있게 된다.
문자열을 받아오려면 nextLine()을 사용하게 되는데, 그 때 큐에 남아있는 공백문자열이 바로 출력되어 넘어가기 때문에 입력을 할 수 없는 것이었다.
(참고한 글)
[JAVA] scanner 버퍼 비우기
JAVA를 사용할 때 Scanner는 정말 많이 쓰이는 라이브러리입니다.
medium.com
최종 코드
import calculator.Calculator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
// Lv 1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기
// 양의 정수(0 포함)를 입력받기
System.out.print("첫번째 숫자를 입력해주세요: ");
int num1 = input.nextInt();
System.out.print("두번째 숫자를 입력해주세요: ");
int num2 = input.nextInt();
if(num1 < 0 || num2 < 0){
System.out.println("0을 포함한 양의 정수만 입력하세요!");
continue;
}
System.out.print("사칙연산 기호(+, -, *, /)를 입력하세요: ");
String operator = input.next();
//버퍼 비우기
input.nextLine();
char oper = operator.charAt(0);
int result = 0;
switch (oper) {
case '+':
result = num1 + num2;
System.out.println("결과: " + result);
break;
case '-':
result = num1 - num2;
System.out.println("결과: " + result);
break;
case '*':
result = num1 * num2;
System.out.println("결과: " + result);
break;
case '/':
try{
result = num1 / num2;
System.out.println("결과: " + result);
}catch(ArithmeticException e){
System.out.println("나눗셈 연산에서 두번째 정수에 0을 입력할 수 없습니다.");
}
break;
default:
System.out.println("잘못된 연산자를 입력하셨습니다!");
}
System.out.println("결과: " + result);
//계속 계산할건지 체크
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
String answer = input.nextLine();
if(answer.equals("exit")){
System.exit(0);
}
}
}
}
'스파르타 내일배움캠프 > TIL(Today I learned)' 카테고리의 다른 글
25.03.04 TIL - final, interface, Lv2. 계산기 과제 (3) | 2025.03.04 |
---|---|
25.02.28 TIL - Wrapper Class, static, final, Interface (2) | 2025.02.28 |
25.02.26 TIL - 조건문, 반복문, 배열, 메서드 (3) | 2025.02.26 |
25.02.25 TIL - Java 변수, 입출력, 연산자 (4) | 2025.02.25 |
25.02.24 TIL - Open JDK, intelliJ 설치, Java 기초 (0) | 2025.02.24 |