자바에는 추상클래스와 인터페이스이 존재한다.
이 둘은 객체지향적인 특성을 더해준다고 한다.
이제 자바를 시작하는 입장에서는 바로 와닿는 개념이 아니라 먼저 정리해보고
더 배워보면 언젠간 무릎을 탁 치는 순간이 오길 바란다.
인터페이스의 효과
느슨한 결합
결합도란 구성 요소 간의 의존성을 의미한다.
어디에 의존 한다는 건 그 요소가 변경되었을 경우 자기도 변경 되어야 한다는 의미이다.
인터페이스는 결합도를 낮출 수 있다.
interface Payment {
void processPayment();
}
class CreditCardPayment implements Payment {
@Override
public void processPayment() {
System.out.println("Processing credit card payment");
}
}
class PaypalPayment implements Payment {
@Override
public void processPayment() {
System.out.println("Processing PayPal payment");
}
}
class PaymentService {
private Payment payment;
public PaymentService(Payment payment) {
this.payment = payment;
}
public void makePayment() {
payment.processPayment();
}
}
여기서 PaymentService는 Payment에 의존한다.
하지만 그 Payment를 구현한 구현체들이 어떻게 구현 됐는지는 알 필요 없이 사용가능하다.
그 구현체가 변경되어도 PaymentService의 코드는 바꿀 필요가 없으니 의존성이 없다는 것
다형성
다형성은 객체지향에서 매우 중요한 개념이라고 한다.
부모 클래스나 인터페이스를 통해 하위 클래스들을 다룰 수 있는 걸 의미한다.
class Main {
public static void main(String[] args) {
Payment payment1 = new CreditCardPayment();
Payment payment2 = new PaypalPayment();
payment1.processPayment(); // Processing credit card payment
payment2.processPayment(); // Processing PayPal payment
}
}
상위 인터페이스인 Payment로 하위클래스 CreditCardPayment와 PaypalPayment를 모두 사용할 수 있다.
의존성 주입
의존성을 외부에서 주입해주는 것
- 생성자 주입(Constructor Injection): 의존성을 생성자의 매개변수로 전달받아 주입하는 방식.
- 세터 주입(Setter Injection): 의존성을 세터 메서드를 통해 주입하는 방식.
- 필드 주입(Field Injection): 의존성을 직접 필드에 주입하는 방식 (주로 프레임워크에서 사용)
이렇게 세 방법이 있다.
생성자 주입
interface MessageService {
void sendMessage(String message);
}
class EmailService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Sending email: " + message);
}
}
class SMSService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Sending SMS: " + message);
}
}
class NotificationService {
private MessageService messageService;
public NotificationService(MessageService messageService) {
this.messageService = messageService;
}
public void notify(String message) {
messageService.sendMessage(message);
}
}
public class Main {
public static void main(String[] args) {
MessageService emailService = new EmailService();
NotificationService notificationService = new NotificationService(emailService);
notificationService.notify("Hello, world!"); // "Sending email: Hello, world!"
MessageService smsService = new SMSService();
notificationService = new NotificationService(smsService);
notificationService.notify("Hello, world!"); // "Sending SMS: Hello, world!"
}
}
NotificationService는 생성자에 의존할 코드를 주입받는다.
세터 주입
public void setMessageService(MessageService messageService) {
this.messageService = messageService;
}
notificationService.setMessageService(emailService);
이렇게 생성자에서 주입하지 않고 세터로 주입 할 수도 있다.
필드 주입은 스프링 배울 때 다시 포스팅 해야겠다.
'공부일지 > Java' 카테고리의 다른 글
[JAVA] String, StringBuffer, StringBuilder (0) | 2024.07.01 |
---|---|
[JAVA] 6/21에 배운 것 (0) | 2024.06.26 |
[JAVA] 6/20 배운거 클래스 (0) | 2024.06.20 |
[JAVA] 추상클래스와 인터페이스 (0) | 2024.06.19 |
[JAVA] Wrapper Class (0) | 2024.06.18 |