자바 프로그래밍에서 인터페이스는 매우 중요하기 때문에 반드시 기억해야 하는 개념입니다. 인터페이스는 객체지향 프로그래밍의 핵심 원칙인 다형성(polymorphism)을 구현하는 데 큰 역할을 합니다. 이 글에서는 자바 인터페이스의 기본적인 개념과 사용법, 장점, 실용 예제를 살펴보겠습니다.
인터페이스란?
인터페이스는 자바에서 클래스가 구현해야 하는 메서드의 집합을 정의하는 데 사용됩니다. 인터페이스 자체는 메서드의 구현을 하지 않고, 메서드의 시그니처(이름, 매개변수, 반환 타입)만을 정의합니다. 인터페이스를 구현하는 클래스에서는 인터페이스에 선언된 모든 메서드를 구현해야 합니다.
선언
인터페이스는 interface 키워드를 사용하여 선언합니다. 예를 들어, 다음은 Animal이라는 인터페이스의 선언입니다.
public interface Animal {
void eat();
void sleep();
void makeSound();
}
위 예제에서 Animal 인터페이스는 eat(), sleep(), makeSound()라는 세 가지 메서드를 정의하고 있습니다. 이 인터페이스는 동물의 공통된 행동을 정의합니다. 어떤 동물인지 구체적으로 알지 못하더라도, 이 인터페이스를 통해 동물의 기본적인 행동을 기대할 수 있습니다. 이 인터페이스를 구현하는 클래스는 반드시 이 세 가지의 메서드들을 구현해야 합니다.
구현
인터페이스를 구현하려면 implements 키워드를 사용합니다. 다음은 Animal 인터페이스를 구현하는 Dog 클래스의 예제입니다.
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog is eating");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping");
}
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
Dog 클래스는 Animal 인터페이스를 구현함으로써, 모든 동물 클래스가 가져야 할 기본 행동을 정의합니다. 이는 코드의 일관성을 유지하고, 다른 동물 클래스와의 상호작용을 쉽게 합니다. 여기서 주의할 점은 구현하는 Dog 클래스는 Animal 인터페이스의 모든 메서드를 구현해야 한다는 점인데요. 그렇지 않으면 컴파일 에러가 발생합니다.
장점
1. 다형성
다형성은 같은 타입이지만 서로 다른 구현을 가진 객체들을 동일한 방식으로 다룰 수 있는 능력을 의미합니다. 자바에서는 인터페이스를 통해 다형성을 구현할 수 있습니다.
예를 들어, 동물을 나타내는 인터페이스인 Animal이 있다고 가정해 봅시다. 이 인터페이스는 eat()과 makeSound()라는 두 가지 메서드를 정의합니다.
public interface Animal {
void eat();
void makeSound();
}
이제 Animal 인터페이스를 구현하는 여러 클래스들을 만들어 보겠습니다.
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog is eating");
}
@Override
public void makeSound() {
System.out.println("Dog barks"); }
}
public class Cat implements Animal {
@Override
public void eat() {
System.out.println("Cat is eating");
}
@Override
public void makeSound() {
System.out.println("Cat meows");
}
}
위의 코드에서 Dog 클래스와 Cat 클래스는 모두 Animal 인터페이스를 구현하고 있습니다. 이제 이들을 다형성을 활용하여 동일한 방식으로 다룰 수 있습니다.
public class AnimalTest {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat(); // 다형성을 이용한 호출
animalMakesSound(dog);
animalMakesSound(cat);
}
public static void animalMakesSound(Animal animal) {
animal.makeSound();
}
}
위의 코드를 실행하면 출력결과는 다음과 같습니다.

위의 AnimalTest 클래스에서 animalMakesSound() 메서드는 Animal 인터페이스를 인자로 받습니다. 이 메서드를 호출할 때 Dog 객체나 Cat 객체를 전달할 수 있습니다. 이는 런타임 시에 메서드가 실제 객체의 타입을 확인하여 적절한 메서드를 호출하기 때문에 가능합니다. 이는 코드를 더욱 유연하게 만들며, 새로운 동물 클래스가 추가되더라도 이 animalMakesSound() 메서드는 변경할 필요가 없습니다.
2. 코드의 유연성 증가
클래스의 구현에 의존하지 않고, 인터페이스를 통해 상호작용하기 때문에 구현체를 쉽게 변경할 수 있습니다. 예를 들어, Payment 인터페이스를 만들어 결제 방법을 추상화하면, 다양한 결제 수단을 쉽게 추가하거나 변경할 수 있습니다. 기존 코드를 수정할 필요 없이 새로운 결제 방식을 추가할 수 있습니다.
3. 다중 상속 효과
자바는 클래스의 다중 상속을 지원하지 않지만, 인터페이스를 사용하여 다중 상속과 유사한 효과를 얻을 수 있습니다. 아래의 예시 코드에서 볼 수 있듯이 Bat이라는 한 클래스가 Animal과 Flying이라는 하나 이상의 인터페이스를 구현할 수 있기 때문입니다.
public class Bat implements Animal, Flying {
@Override
public void eat() {
System.out.println("Bat is eating");
}
@Override
public void sleep() {
System.out.println("Bat is sleeping");
}
@Override
public void makeSound() {
System.out.println("Bat screeches");
}
@Override
public void fly() {
System.out.println("Bat is flying");
}
}
Bat 클래스는 Animal과 Flying 인터페이스를 동시에 구현함으로써, 여러 타입의 행동을 정의할 수 있습니다. 이는 코드의 재사용성을 높이고, 다양한 기능을 하나의 클래스에 통합할 수 있게 합니다.
실용 예제
다음은 인터페이스를 활용한 간단한 예제입니다. 이 예제에서는 다양한 결제 수단을 처리하는 인터페이스를 정의하고 이를 구현하는 클래스를 작성합니다. 먼저, 아래와 같이 인터페이스를 정의합니다.
public interface Payment {
void pay(int amount);
}
Payment 인터페이스는 결제 수단이 가져야 할 공통적인 pay 메서드를 정의합니다. 이는 결제 수단에 상관없이 일관된 결제 처리를 가능하게 합니다.
다음은 결제 구현 클래스 코드입니다.
public class CreditCardPayment implements Payment {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card");
}
}public class PayPalPayment implements Payment {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal");
}
}
CreditCardPayment와 PayPalPayment 클래스는 각각 신용카드와 PayPal 결제 방법을 구현합니다. 이 클래스들은 Payment 인터페이스를 구현하여 일관된 pay 메서드를 제공합니다.
다음은 결제를 처리하는 메서드입니다.
public class PaymentProcessor {
public void processPayment(Payment payment, int amount) {
payment.pay(amount);
}
}ublic class Main {
public static void main(String[] args) {
PaymentProcessor processor = new PaymentProcessor();
Payment creditCard = new CreditCardPayment();
Payment payPal = new PayPalPayment();
processor.processPayment(creditCard, 100);
processor.processPayment(payPal, 200);
}
}
위의 메인 클래스를 실행하면 다음과 같이 출력됩니다.

PaymentProcessor 클래스는 결제 방식을 구체적으로 알 필요 없이 Payment 인터페이스를 통해 결제를 처리합니다. 이를 통해 결제 방식이 추가되거나 변경되더라도 PaymentProcessor 클래스는 수정될 필요가 없습니다.
결론
자바 인터페이스는 코드의 유연성과 재사용성을 제공합니다. 인터페이스를 활용하면 다형성을 구현할 수 있으며, 이를 통해 코드의 유지보수성을 높일 수 있습니다. 다양한 구현체를 통해 인터페이스를 사용하는 방법을 익히면 자바 프로그래밍에서 더욱 효율적으로 문제를 해결할 수 있습니다.
2024.05.21 - [Java] - 자바(Java) 추상 클래스(Abstract class)의 정의와 목적, 사용법과 예시, 주의사항
자바(Java) 추상 클래스(Abstract class)의 정의와 목적, 사용법과 예시, 주의사항
자바 프로그래밍 언어에서 추상클래스는 객체 지향 프로그래밍의 핵심 개념 중 하나입니다. 이는 클래스 계층구조에서 상위 클래스의 역할을 하며, 다른 클래스들이 상속받아 구체화할 수 있는
it-learner.tistory.com