3주차 학습 진도 : Chapter 6 (클래스)
6-1 객체 지향 프로그래밍
객체 지향 프로그래밍(Object-Oriented Programming, OOP)은 현실 세계의 객체를 프로그래밍 언어로 표현하는 방식입니다. 객체는 속성(필드)과 행동(메소드)을 가지고 있으며, 객체들 간의 상호작용을 통해 프로그램이 동작합니다.
객체의 상호작용
객체는 다른 객체와 상호작용하며, 이를 통해 프로그램의 기능이 구현됩니다. 객체 간의 상호작용은 메시지 전송을 통해 이루어지며, 메시지를 받은 객체는 자신의 메소드를 실행하여 응답합니다.
객체와 클래스
객체는 클래스의 인스턴스입니다. 클래스는 객체의 설계도로, 객체의 속성과 행동을 정의합니다. 클래스를 사용하면 동일한 특성을 가진 객체를 쉽게 생성할 수 있습니다.
클래스 선언
클래스는 다음과 같은 형태로 선언합니다:
[접근 제한자] class 클래스이름 {
// 필드 선언
// 생성자 선언
// 메소드 선언
}
접근 제한자는 public, protected, private, default 중 하나를 사용할 수 있습니다.
객체 생성과 클래스 변수
객체는 new 연산자를 사용하여 생성합니다:
클래스 변수(객체명) = new 클래스();
클래스 변수는 클래스 내부에 선언되며, 모든 객체가 공유합니다. 클래스 변수는 static 키워드를 사용하여 선언합니다.
6-2 필드
필드는 클래스 내부에 선언되는 변수로, 객체의 상태를 나타냅니다. 필드는 다음과 같이 선언할 수 있습니다:
[접근 제한자] [static] 데이터 타입 필드명;
필드는 객체 생성 시 자동으로 초기화되며, 객체의 메소드에서 사용할 수 있습니다.
6-3 생성자
생성자는 객체를 생성할 때 자동으로 호출되는 메소드입니다. 생성자는 다음과 같이 선언할 수 있습니다:
[접근 제한자] 클래스([매개변수, ...]) {
// 객체의 초기화 코드
}
기본 생성자는 매개변수가 없는 생성자이며, 생성자 오버로딩을 통해 다양한 생성자를 정의할 수 있습니다. this()를 사용하면 다른 생성자를 호출할 수 있습니다.
6-4 메소드
메소드는 객체의 행동을 정의하는 함수입니다. 메소드는 다음과 같이 선언할 수 있습니다:
[접근 제한자] [static] 반환 타입 메소드명([매개변수, ...]) {
// 메소드 코드
return 반환값;
}
메소드 호출은 객체 참조 변수를 사용하여 이루어집니다:
객체명.메소드명([인수, ...]);
메소드 오버로딩을 통해 같은 이름의 메소드를 여러 개 정의할 수 있습니다.
6-5 인스턴스 멤버와 정적 멤버
인스턴스 멤버는 객체마다 독립적으로 존재하는 필드와 메소드이며, this 키워드를 사용하여 접근할 수 있습니다.
정적 멤버는 클래스 단위로 존재하는 필드와 메소드이며, 객체 생성 없이 클래스 이름으로 접근할 수 있습니다.
싱글톤 패턴은 클래스의 인스턴스를 하나만 생성하도록 보장하는 디자인 패턴입니다. 이를 위해 생성자를 private으로 선언하고, 정적 메소드를 통해 유일한 인스턴스를 반환합니다.
final 필드와 상수
final 키워드를 사용하면 필드의 값을 변경할 수 없습니다. 상수는 final 필드 중에서 값이 변경되지 않는 필드를 의미합니다.
6-6 패키지와 접근 제한자
패키지는 클래스를 그룹화하는 단위이며, 패키지 선언을 통해 클래스의 소속을 지정할 수 있습니다.
접근 제한자는 클래스, 생성자, 필드, 메소드의 접근 범위를 제한합니다. public, protected, private, default(package-private) 중 하나를 사용할 수 있습니다.
Getter와 Setter 메소드
필드의 값을 안전하게 접근하고 변경하기 위해 Getter와 Setter 메소드를 사용합니다. Getter 메소드는 필드 값을 반환하고, Setter 메소드는 필드 값을 설정합니다.
package sec06.exam07;
public class Car {
private String make;
private String model;
private int year;
private int mileage;
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
this.mileage = 0;
}
public Car(String make, String model, int year, int mileage) {
this(make, model, year);
this.mileage = mileage;
}
public void drive(int distance) {
this.mileage += distance;
}
public int getMileage() {
return this.mileage;
}
public void setMileage(int mileage) {
this.mileage = mileage;
}
public String getMake() {
return this.make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return this.model;
}
public int getYear() {
return this.year;
}
public void setYear(int year) {
this.year = year;
}
}
package sec06.exam07;
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car("Genesis", "GV80", 2020);
myCar.drive(10000);
System.out.println("[ " + myCar.getMake() + " " + myCar.getModel() + " ] " + "Mileage: " + myCar.getMileage());
Car anotherCar = new Car("Hyundai", "IONIQ 5", 2021, 5000);
anotherCar.drive(2500);
System.out.println("[ " + anotherCar.getMake() + " " + anotherCar.getModel() + " ] " + "Mileage: " + anotherCar.getMileage());
}
}
챕터6 클래스 에서 학습한 내용들을 정리해서 하나의 에제 자바 코드를 작성해 보았습니다.
요즘 배민원(배달의민족) 에서 자영업자 사장님들이 지불하던 배달 중계수수료를 올리고, 배민 주문하는 이용자들에게 다음달부터 배민클럽 유료로 비용을 부과한다고 하여 많은 언론 기사들이 나오던데, 정확하지는 않지만, 궁굼해서 수수료가 어떻게 되는지, 언론에 보도된 기사를 참고해서 이번주에 학습한 자바 클래스를 이용해서 코드를 작성해 봤습니다.
배민(배달의민족)에서 가져가는 수수료가 배달비가 포함되어 있다지만 음식 주문 금액이 많이 질수록 생각보다 부담스러울 정도로 많이 가져가기는 하네요.
package sec06.exam07;
public class baemin1Fee {
private final double commissionRate = 0.098; // 중계이용료 9.8%
private final double vatRate = commissionRate * 0.1; // 부가세(중계이용료의 10%) 10%
private final double deliveryFee = 2900; // 사장님 부담 배달비
private final double cardFee = 0.033; // 카드결제수수료 (부가세 10% 포함) 3.3%
public double getCommissionRate() {
return commissionRate;
}
public double getVatRate() {
return vatRate;
}
public double getDeliveryFee() {
return deliveryFee;
}
public double getCardFee() {
return cardFee;
}
}
package sec06.exam07;
import java.util.Scanner;
public class baemin1Charge {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("주문금액을 입력하세요: ");
double orderAmount = sc.nextInt();
baemin1Fee fee = new baemin1Fee();
double commission = fee.getCommissionRate() * orderAmount;
double vat = fee.getVatRate() * orderAmount;
double cardFee = fee.getCardFee() * orderAmount;
double totalFee = commission + vat + cardFee + fee.getDeliveryFee();
double remainingAmount = orderAmount - totalFee;
System.out.println("=====================================================");
System.out.println("===== 2024.8.9일 이후 서울시 기준 배민원 사장님 수수료 =====");
System.out.println("=====================================================");
System.out.printf("중 계 이 용 료 : %.1f원\n", commission);
System.out.printf("부 가 세: %.1f원\n", vat);
System.out.printf("사장님 부담 배달비: %.1f원\n", fee.getDeliveryFee());
System.out.printf("카 드 수 수 료: %.1f원\n", cardFee);
System.out.printf("총 부 담 금: \u001B[31m%.1f원\u001B[0m\n", totalFee);
System.out.printf("배민원 공제후 금액: \u001B[34m%.1f원\u001B[0m\n", remainingAmount);
System.out.println("=====================================================");
}
}
음식주문 1만원을 했을때 배민 수수료 입니다.
주문금액을 입력하세요: 10000
=====================================================
===== 2024.8.9일 이후 서울시 기준 배민원 사장님 수수료 =====
=====================================================
중 계 이 용 료 : 980.0원
부 가 세: 98.0원
사장님 부담 배달비: 2900.0원
카 드 수 수 료: 330.0원
총 부 담 금: 4308.0원
배민원 공제후 금액: 5692.0원
=====================================================
음식주문 5만원을 했을때 배민 수수료 입니다.
주문금액을 입력하세요: 50000
=====================================================
===== 2024.8.9일 이후 서울시 기준 배민원 사장님 수수료 =====
=====================================================
중 계 이 용 료 : 4900.0원
부 가 세: 490.0원
사장님 부담 배달비: 2900.0원
카 드 수 수 료: 1650.0원
총 부 담 금: 9940.0원
배민원 공제후 금액: 40060.0원
=====================================================
1만원 짜리 음식을 주문하면 배민에서 중계수수료, 카드수수료, 배달비 등으로 4300원 정도 가져가고, 5만원 짜리 음식을 주문하면 1만원 정도를 중계수수료, 카드수수료, 배달비 등으로 가져가네요. 생각보다 많이 배민에서 가져가서 놀랐네요…
참고로 위에 수수료에는 음식점 사장님 별로 광고비와 쿠폰 등의 추가적인 비용은 빠져 있습니다.
위에 코드에서 결과 하면에서 색상이 제대로 보여지지 않는데, 작성한 코드에서 총 부담금에 ‘\u001B[31m’ 는 ANSI 이스케이프 코드로 빨간색으로 출려하려고 추가한 것이고, 공제후 금액에 ‘\u001B[34m’는 파란색으로 출력하기 위해서 추가한 코드 입니다.
ANSI 이스케이프 코드를 활용하면 출력된 코드에 원하는 색상으로 출력할수 있어서 텍스트로 코딩하는데 또 다른 재미인듯 합니다.
기본 숙제(필수) : 어렵거나 중요하다고 생각되는 용어를 혼공 용어 노트에 정리하고 공유하기
- 오버로딩 : 클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것을 메소드 오버로딩(overloading)이라고 합니다. 메소드 오버로딩의 조건은 매개변수의 타입, 개수, 순서 중 하나가 달라야 한다는 점입니다.
- 싱글톤 : 전체 프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우가 있습니다. 단 하나만 생성된다고 해서 이 객체를 싱글톤(Singleton)이라고 합니다.
- Getter/Setter : 필드는 외부에서 접근할 수 없도록 막고 메소드는 공개해서 외부에서 메소드를 통해 필드에 접근하도록 유도합니다. 필드의 값을 외부로 리턴해주는 메소드를 Getter라고 하고 외부에서 값을 받아 필드를 변경하는 메소드를 Setter라고 합니다.
추가 숙제(선택) : 객체 지향 프로그래밍의 개념 정리하기
객체 지향 프로그래밍의 주요 개념은 객체, 클래스, 캡슐화, 상속, 그리고 다형성입니다.
객체는 현실 세계의 사물이나 개념을 프로그램 내에서 모방한 것으로, 속성(데이터)과 행동(메서드)을 가지고 있습니다. 클래스는 객체를 정의하는 설계도 역할을 하며, 클래스 내부에 속성과 메서드가 정의됩니다. 클래스를 통해 객체를 생성할 수 있습니다.
캡슐화는 객체의 내부 구현 세부 사항을 감추고 제한된 인터페이스로만 접근하게 함으로써, 데이터 보호와 정보 은닉을 실현할 수 있습니다. 상속은 기존 클래스의 속성과 메서드를 물려받아 새로운 클래스를 정의하는 것으로, 상위 클래스의 특성을 하위 클래스가 재사용할 수 있습니다. 이를 통해 계층적 구조를 만들 수 있습니다.
마지막으로 다형성은 하나의 객체가 여러 형태를 가질 수 있는 능력을 말합니다. 메서드 오버로딩과 오버라이딩을 통해 구현되며, 유연성 있는 코드 작성이 가능합니다.
이러한 OOP 개념들은 모듈성, 재사용성, 유지보수성 등 프로그램의 질을 높이는 데 도움을 줍니다.