동적 바인딩은 프로그램 실행 시점에 어떤 메서드나 함수가 호출될지 결정되는 방식입니다. 이는 객체 지향 프로그래밍(OOP)의 특징중 하나로 다형성을 구현하는데 사용.
정적 바인딩(Static Binding) : 컴파일 시점에 메서드 호출이 결정
동적 바인딩(Dynamic Binding) : 실행 시점에 객체의 실제타입을 기준으로 호출할 메서드가 결정되는 방식.
참조 변수의 타입이 아닌 실제 객체의 타입에 따라 호출되는 메서드가 결정.
class Parent {
void display() {
System.out.println("Parent의 display 메서드 호출");
}
}
class Child extends Parent {
@Override
void display() {
System.out.println("Child의 display 메서드 호출");
}
}
public class DynamicBindingExample {
public static void main(String[] args) {
Parent obj = new Child(); // Parent 타입의 참조 변수, 실제 객체는 Child
obj.display(); // 실행 시점에 Child의 display() 호출
}
}
다형성 구현으로 인해 하나의 참조 변수로 다양한 객체를 처리할 수 있으며, 객체의 타입이 변경되어도 코드 수정 없이 새로운 동작을 추가할 수 있다. 또한 부모 클래스의 메서드를 오버라이딩하여 자식 클래스에서 특정 동작을 구현할 수 있다.
주로 상속 관계에서 부모 클래스의 메서드를 자식 클래스가 재사용할 때 사용되거나 추상 클래스 및 인터페이스를 통하여 변수를 받아서 런타임에 실제 구현 클래스의 메서드가 호출되게 하도록 사용합니다.
주의할 점
동적 바인딩(Dynamic Binding)은 객체 지향 프로그래밍(OOP)의 핵심 개념인 다형성과 관련이 깊어서, 신입 백엔드 개발자가 실습을 통해 충분히 익힐 만한 주제입니다. 다음은 동적 바인딩을 실습할 수 있는 아이디어와 예제입니다.
RequestHandler 클래스를 설계하여, GET, POST 등 HTTP 메서드를 자식 클래스에서 오버라이딩.class RequestHandler {
void handleRequest() {
System.out.println("Default request handling");
}
}
class GetRequestHandler extends RequestHandler {
@Override
void handleRequest() {
System.out.println("Handling GET request");
}
}
class PostRequestHandler extends RequestHandler {
@Override
void handleRequest() {
System.out.println("Handling POST request");
}
}
public class BackendDynamicBinding {
public static void main(String[] args) {
RequestHandler handler;
// 동적 바인딩으로 런타임에 객체 타입에 따라 동작이 결정됨
handler = new GetRequestHandler();
handler.handleRequest();
handler = new PostRequestHandler();
handler.handleRequest();
}
}
interface DatabaseConnector {
void connect();
}
class MySQLConnector implements DatabaseConnector {
@Override
public void connect() {
System.out.println("Connecting to MySQL...");
}
}
class PostgreSQLConnector implements DatabaseConnector {
@Override
public void connect() {
System.out.println("Connecting to PostgreSQL...");
}
}
class BackendService {
private DatabaseConnector connector;
public BackendService(DatabaseConnector connector) {
this.connector = connector; // 의존성 주입
}
public void start() {
connector.connect(); // 동적 바인딩
System.out.println("Service started!");
}
}
public class DynamicBindingDI {
public static void main(String[] args) {
DatabaseConnector mysql = new MySQLConnector();
DatabaseConnector postgres = new PostgreSQLConnector();
BackendService service = new BackendService(mysql);
service.start();
service = new BackendService(postgres);
service.start();
}
}
interface Controller {
void execute();
}
class HomeController implements Controller {
@Override
public void execute() {
System.out.println("Home Page");
}
}
class LoginController implements Controller {
@Override
public void execute() {
System.out.println("Login Page");
}
}
class WebServer {
public void handleRequest(String url) {
Controller controller;
if (url.equals("/home")) {
controller = new HomeController();
} else if (url.equals("/login")) {
controller = new LoginController();
} else {
System.out.println("404 Not Found");
return;
}
controller.execute(); // 동적 바인딩
}
}
public class WebServerSimulation {
public static void main(String[] args) {
WebServer server = new WebServer();
server.handleRequest("/home");
server.handleRequest("/login");
server.handleRequest("/unknown");
}
}
abstract class EventHandler {
abstract void handleEvent(String data);
}
class ChatEventHandler extends EventHandler {
@Override
void handleEvent(String data) {
System.out.println("Chat Message Received: " + data);
}
}
class NotificationEventHandler extends EventHandler {
@Override
void handleEvent(String data) {
System.out.println("Notification Sent: " + data);
}
}
public class EventHandlerSimulation {
public static void main(String[] args) {
EventHandler eventHandler;
eventHandler = new ChatEventHandler();
eventHandler.handleEvent("Hello!");
eventHandler = new NotificationEventHandler();
eventHandler.handleEvent("You've got a new follower!");
}
}
위 실습들은 기초부터 중급 수준까지 다양하게 구성되어 있어, 신입 개발자로서 충분히 도전할 만합니다. 🌟