자바 - 인터페이스

신입 프로그래머 여러분, 환영합니다! 오늘은 자바 인터페이스의 흥미로운 세계에 빠지게 될 것입니다. 프로그래밍에 새로운 여러분도 걱정하지 마세요; 저는 수많은 학생들을 가르쳐온 년月들 동안처럼 단계별로 이 개념을 안내해 드릴 것입니다. 그럼, 좋아하는 음료수를 들고 편하게 앉아서 함께 이 흥미로운 여정에 떠나보겠습니다!

Java - Interfaces

자바 인터페이스란 무엇인가요?

로봇을 만드는 것을 상상해 보세요 (이 역할에 잠시 맡겨 주세요, 이 비유는 곧 이해될 것입니다!). 여러분의 로봇이 특정 작업을 할 수 있어야 한다는 것을 알고 있습니다, 예를 들어 이동하고 소리를 내는 것이죠, 하지만 어떻게 이러한 작업을 할 것인지 아직 확실하지 않습니다. 자바에서 인터페이스는 여러분의 로봇에 대한 블루프린트와 비슷합니다. 로봇이 무엇을 할 수 있어야 하는지를 정의하지만, 그 방법에 대해서는 지정하지 않습니다.

프로그래밍 용어로는, 인터페이스는 클래스가 구현해야 하는 일련의 추상 메서드를 지정하는 계약입니다. 이는 추상화를 이루고 여러 클래스가 공유할 수 있는 공통 동작을 정의하는 방법입니다.

자바에서 인터페이스 선언

간단한 예제로 시작해 보겠습니다. 여기서는 인터페이스를 어떻게 선언하는지 보겠습니다:

public interface Robot {
void move();
void makeSound();
}

이 예제에서, Robot라는 인터페이스를 선언했고, 두 개의 추상 메서드인 move()makeSound()이 있습니다. 이 메서드들에는 몸체가 없다는 것에 주목하세요 - 그들은 단지 선언일 뿐입니다. 이 인터페이스를 구현하는 클래스들이 이러한 메서드의 실제 코드를 제공해야 합니다.

자바 인터페이스의 속성

더 나아가기 전에, 자바 인터페이스의 몇 가지 주요 속성을 빠르게 요약해 보겠습니다:

  1. 인터페이스의 모든 메서드는 묵시적으로 공개(public)와 추상(abstract)입니다.
  2. 인터페이스는 직접 인스턴스화될 수 없습니다.
  3. 인터페이스는 여러 인터페이스를 확장할 수 있습니다.
  4. 인터페이스의 변수는 묵시적으로 공개(public), 정적(static), 최종(final)입니다.

자바에서 인터페이스 구현

이제 Robot 인터페이스를 가지고 있으므로, 이를 구현하는 클래스를 만들어 보겠습니다. 이 클래스를 AndroidRobot라고 부르겠습니다:

public class AndroidRobot implements Robot {
@Override
public void move() {
System.out.println("안드로이드 로봇이 두 다리를 걸어서 걷습니다.");
}

@Override
public void makeSound() {
System.out.println("안드로이드 로봇이 말합니다: '안녕, 인간!'");
}
}

여기서, implements 키워드를 사용하여 우리의 AndroidRobot 클래스가 Robot 인터페이스를 구현하고 있다는 것을 나타냅니다. 그런 다음 move()makeSound() 메서드에 대한 구현을 제공합니다.

이를 분석해 보겠습니다:

  1. @Override 어노테이션은 선택 사항이지만, 권장됩니다. 이는 컴파일러에게 우리가 인터페이스에서 메서드를 의도적으로 재정의하고 있다는 것을 알려줍니다.
  2. 우리는 move()makeSound()에 특정한 구현을 제공했습니다. 우리의 안드로이드 로봇은 두 다리를 걸며 '안녕'라고 말할 수 있습니다!

인터페이스와 클래스 사용

이제, 우리의 새로운 인터페이스와 클래스를 어떻게 사용할 수 있는지 살펴보겠습니다:

public class RobotDemo {
public static void main(String[] args) {
Robot myRobot = new AndroidRobot();
myRobot.move();
myRobot.makeSound();
}
}

이 코드를 실행하면 다음과 같은 출력이 나옵니다:

안드로이드 로봇이 두 다리를 걸어서 걷습니다.
안드로이드 로봇이 말합니다: '안녕, 인간!'

myRobotRobot(인터페이스) 형식으로 선언했지만, AndroidRobot으로 인스턴스화했음을 주목하세요. 이는 인터페이스의 강력한 기능입니다 - 우리는 구현에 대해 프로그래밍할 수 있지만, 인터페이스에 의존할 수 있습니다. 이는 우리의 코드를 더 유연하고 미래에 변경하기 쉽게 만듭니다.

자바 인터페이스 확장

클래스와 마찬가지로, 인터페이스도 다른 인터페이스를 확장할 수 있습니다. 이를 통해 더 특화된 인터페이스를 만들 수 있습니다. 더 복잡한 로봇 인터페이스를 만들어 보겠습니다:

public interface AdvancedRobot extends Robot {
void fly();
void swim();
}

이제 AdvancedRobot을 구현하는 모든 클래스는 move(), makeSound(), fly(), swim() 메서드에 대한 구현을 제공해야 합니다.

인터페이스와 다중 상속

클래스는 하나의 슈퍼클래스만 확장할 수 있는 반면, 인터페이스는 여러 인터페이스를 확장할 수 있습니다. 이는 자바에서 다중 상속을 구현하는 방법 중 하나입니다. 예를 들어:

public interface Flying {
void takeOff();
void land();
}

public interface Swimming {
void dive();
void surface();
}

public interface AmphibiousRobot extends Robot, Flying, Swimming {
void transformMode();
}

AmphibiousRobot을 구현하는 클래스는 Robot, Flying, Swimming, AmphibiousRobot의 모든 메서드에 대한 구현을 제공해야 합니다.

인터페이스의 디폴트 메서드

자바 8부터, 인터페이스는 디폴트 메서드를 가질 수 있습니다 - 디폴트 구현이 있는 메서드입니다. 이 기능은 인터페이스에 새로운 메서드를 추가할 때 기존 구현에 영향을 주지 않도록 도와주기 위해 도입되었습니다. 예를 들어:

public interface ModernRobot {
void process();

default void boot() {
System.out.println("부팅 중...");
process();
System.out.println("부팅 완료!");
}
}

ModernRobot을 구현하는 클래스는 process()를 구현해야 하지만, boot()는 무료로 얻습니다. 그들은 boot()를 재정의할 수 있지만, 필요는 없습니다.

함수형 인터페이스

함수형 인터페이스는 정확히 하나의 추상 메서드를 포함하는 인터페이스입니다. 이는 자바의 람다 표현식에 중요합니다. 예를 들어:

@FunctionalInterface
public interface Calculator {
int calculate(int a, int b);
}

이 인터페이스를 람다 표현식으로 사용할 수 있습니다:

Calculator add = (a, b) -> a + b;
System.out.println(add.calculate(5, 3));  // 출력: 8

결론

우와! 오늘은 많은 내용을 다루었습니다. 기본적인 인터페이스 선언부터 함수형 인터페이스까지, 여러분은 이제 자바 인터페이스에 대한 견고한 기반을 갖추었습니다. 인터페이스는 자바 프로그래밍에서 강력한 도구입니다. 이를 통해 우리는 공통 동작을 정의하고, 다중 상속을 이루고, 더 유연하고 유지보수하기 쉬운 코드를 작성할 수 있습니다.

자바 여정을 계속하면서, 인터페이스는 어디서나 등장하게 될 것입니다. 자바의 표준 라이브러리와 많은 디자인 패턴에서 广泛に 사용됩니다. 그럼 계속 연습하고, 곧 전문가급으로 인터페이스를 사용할 수 있을 거예요!

코딩을 즐기세요, 미래의 자바 마스터 여러분! ??‍??‍?

Credits: Image by storyset