자바 - 인터페이스의 기본 메서드

안녕하세요, 미래의 자바 마법사 여러분! 오늘, 우리는 자바의 기본 메서드의 세계로 흥미진진한 여정을 떠날 거예요. 프로그래밍에 새로운 사람이신 건 두렵지 않게, 저는 여러분의 친절한 가이드가 될 거예요. 여러분과 함께 이 개념을 단계별로 탐구할 거예요. 그럼, 가상의 방망이(또는 키보드)를 잡고, 몸을 던져볼까요!

Java - Default Methods

기본 메서드란 무엇인가요?

자신이 큰 가족(인터페이스 가족이라고 부를게요) 일부라고 상상해봅시다. 그리고 여러분은 항상 모두가 따르는 규칙들을 가지고 있었죠. 하지만 갑자기 새로운 규칙이 필요하다는 것을 깨닫고, 모든 가족 구성원에게 그것을 즉시 실행하도록 강요하고 싶지 않다면요. 이때 기본 메서드가 구조대를 나타냅니다!

자바에서는 기본 메서드를 사용하여 인터페이스에 새로운 메서드를 추가할 수 있으며, 이를 구현하는 클래스들을 깨뜨리지 않습니다. 이는 가족에 새로운 규칙을 추가하는 것과 같지만, 모든 사람에게 디폴트 방법을 제공하여 자신만의 방법을 정하지 않고도 따를 수 있게 하는 것입니다.

문법

다음과 같이 기본 메서드를 선언합니다:

public interface MyInterface {
default void myDefaultMethod() {
System.out.println("This is a default method");
}
}

메서드 선언 앞에 default 키워드가 들어간다는 것을 봐요. "당신이 자신만의 방법을 없다면, 여기 기본 방법이 있어요!"라고 말하는 것과 같아요!

자바 기본 메서드 예제

자, 더 구체적인 예제를 살펴보죠. 여러분이 간단한 게임을 만드는데, 다양한 캐릭터들이 행동을 할 수 있다고 생각해봅시다.

public interface Character {
void move();

default void speak() {
System.out.println("Hello, I'm a character in this game!");
}
}

public class Hero implements Character {
@Override
public void move() {
System.out.println("Hero moves swiftly");
}
}

public class Villain implements Character {
@Override
public void move() {
System.out.println("Villain sneaks around");
}

@Override
public void speak() {
System.out.println("I am the villain! Fear me!");
}
}

public class GameDemo {
public static void main(String[] args) {
Character hero = new Hero();
Character villain = new Villain();

hero.move();    // 출력: Hero moves swiftly
hero.speak();   // 출력: Hello, I'm a character in this game!

villain.move(); // 출력: Villain sneaks around
villain.speak(); // 출력: I am the villain! Fear me!
}
}

이 예제에서는 기본 speak() 메서드가 있는 Character 인터페이스를 가지고 있습니다. Hero 클래스는 기본 구현을 사용하고, Villain 클래스는 이를 오버라이드합니다. 이는 캐릭터에 기본 대사를 제공하는 것과 같지만, 악당이 자신만의 드라마틱한 대사를 가질 수 있게 합니다!

다중 상속에서 기본 메서드

이제 조금 더 복잡한 상황을 살펴보죠. 클래스가 같은 이름의 기본 메서드를 가진 여러 인터페이스를 구현하는 경우 어떻게 될까요? 이는 두 가족원이 여러분에게 다른 조언을 준다고 생각할 수 있습니다!

public interface Flyer {
default void takeOff() {
System.out.println("Flyer is taking off");
}
}

public interface Spaceship {
default void takeOff() {
System.out.println("Spaceship is launching");
}
}

public class FlyingSpaceship implements Flyer, Spaceship {
// 충돌을 해결하기 위해 takeOff 메서드를 오버라이드 해야 합니다
@Override
public void takeOff() {
Flyer.super.takeOff(); // Flyer의 takeOff 메서드 호출
Spaceship.super.takeOff(); // Spaceship의 takeOff 메서드 호출
}
}

public class SpaceDemo {
public static void main(String[] args) {
FlyingSpaceship ship = new FlyingSpaceship();
ship.takeOff();
}
}

이 경우, FlyingSpaceship는 충돌을 해결하기 위해 takeOff() 메서드를 오버라이드해야 합니다. 이는 가족에서 외교관이 되어 두 가지 조언을 모두 따를 수 있는 방법을 찾는 것과 같습니다!

자바의 정적 기본 메서드

허리케인을 잡아주세요, 왜냐하면 이제 플롯 트위스트가 올 테니까요! 자바는 인터페이스에서 정적 기본 메서드를 허용하지 않습니다! 하지만 걱정 마세요, 이는 좋은 이유가 있습니다. 정적 메서드는 인터페이스 자체에 속해 있으며, 이를 구현하는 객체에는 속하지 않습니다.

그러나 자바 8은 인터페이스에서 정적 메서드를 도입했습니다. 어떻게 작동하는지 살펴보죠:

public interface MathOperations {
static int add(int a, int b) {
return a + b;
}

default int subtract(int a, int b) {
return a - b;
}
}

public class Calculator implements MathOperations {
// 정적 메서드는 구현할 필요 없음
}

public class MathDemo {
public static void main(String[] args) {
Calculator calc = new Calculator();

System.out.println("5 + 3 = " + MathOperations.add(5, 3)); // 인터페이스에서 정적 메서드 호출
System.out.println("5 - 3 = " + calc.subtract(5, 3)); // 기본 메서드를 객체로 호출
}
}

여기서, add()MathOperations 인터페이스에 속하는 정적 메서드이고, subtract()는 인터페이스를 구현하는 모든 클래스에서 사용할 수 있는 기본 메서드입니다.

결론

그렇게 끝나버렸어요, 여러분은 자바의 제자 여러분! 우리는 기본 메서드의 땅을 거쳐 여정을 했고, 다중 상속 시나리오를 탐구했고, 인터페이스의 정적 메서드에도 얼마나 다가갔는지 살펴보았습니다. 기본 메서드는 자바 도구箱의 스위스 Army 톱니칼과 같아요 – 인터페이스에 새로운 기능을 추가할 때 기존 구현을 깨뜨리지 않도록 도와줍니다.

기억하죠, 큰 힘에는 큰 책임이 따르죠. 기본 메서드를 지혜롭게 사용하여 인터페이스를 진화시키면서 역전적 호환성을 유지하세요. 코딩하는 시간이 행복하고, 자바 모험이 버그 없이 기본 메서드 마법으로 가득 차길 바랍니다!

메서드 유형 문법 사용
기본 메서드 default returnType methodName(parameters) { // 구현 } 인터페이스에서 기본 구현을 제공하는 데 사용
정적 메서드 static returnType methodName(parameters) { // 구현 } 인터페이스에서 유틸리티 메서드를 사용할 때, 인스턴스가 필요하지 않음
추상 메서드 returnType methodName(parameters); 인터페이스에서 메서드를 선언하고 구현하지 않음

Credits: Image by storyset