자바

자바 인터페이스 완벽 가이드

끄적인다 2024. 6. 28. 19:00
반응형

자바(Java)에서 인터페이스(Interface)는 객체 지향 프로그래밍의 중요한 개념 중 하나입니다. 인터페이스는 클래스가 구현해야 하는 메서드의 집합을 정의하며, 클래스 간의 계약을 명확히 하고 다형성을 지원합니다. 이 글에서는 인터페이스의 개념, 사용 이유, 장점, 인터페이스의 선언과 구현 방법, 인터페이스와 관련된 주요 키워드와 개념을 자세히 살펴보겠습니다.

1. 인터페이스란 무엇인가?

인터페이스는 추상 메서드(구현되지 않은 메서드)와 상수를 포함할 수 있는 일종의 추상 타입입니다. 인터페이스는 클래스가 특정 메서드를 구현하도록 강제하는 계약 역할을 합니다.

예시

interface Animal {
    void eat();
    void sleep();
}

class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("Dog is eating");
    }

    @Override
    public void sleep() {
        System.out.println("Dog is sleeping");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.eat();   // 출력: Dog is eating
        myDog.sleep(); // 출력: Dog is sleeping
    }
}

2. 인터페이스를 사용하는 이유

1. 다형성(Polymorphism) 지원

인터페이스를 통해 다양한 클래스가 동일한 메서드를 구현하도록 할 수 있습니다. 이는 다형성을 구현하는 데 중요한 역할을 합니다.

interface Animal {
    void makeSound();
}

class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof");
    }
}

class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        Animal myCat = new Cat();
        
        myDog.makeSound(); // 출력: Woof
        myCat.makeSound(); // 출력: Meow
    }
}

2. 코드의 유연성과 확장성 향상

인터페이스를 사용하면 코드의 유연성과 확장성을 높일 수 있습니다. 새로운 기능이 필요할 때 기존 코드를 수정하지 않고 새로운 클래스를 추가할 수 있습니다.

interface Payment {
    void pay(int amount);
}

class CreditCardPayment implements Payment {
    @Override
    public void pay(int amount) {
        System.out.println("Paid " + amount + " using Credit Card");
    }
}

class PayPalPayment implements Payment {
    @Override
    public void pay(int amount) {
        System.out.println("Paid " + amount + "using PayPal");
    }
}

public class Main {
    public static void main(String[] args) {
        Payment payment = new CreditCardPayment();
        payment.pay(100); // 출력: Paid 100 using Credit Card

        payment = new PayPalPayment();
        payment.pay(200); // 출력: Paid 200 using PayPal
    }
}

3. 다중 상속의 대안

자바는 클래스의 다중 상속을 지원하지 않습니다. 그러나 인터페이스를 사용하면 여러 인터페이스를 구현함으로써 다중 상속과 유사한 효과를 얻을 수 있습니다.

interface Drivable {
    void drive();
}

interface Flyable {
    void fly();
}

class FlyingCar implements Drivable, Flyable {
    @Override
    public void drive() {
        System.out.println("Driving");
    }

    @Override
    public void fly() {
        System.out.println("Flying");
    }
}

public class Main {
    public static void main(String[] args) {
        FlyingCar myFlyingCar = new FlyingCar();
        myFlyingCar.drive(); // 출력: Driving
        myFlyingCar.fly();   // 출력: Flying
    }
}

3. 인터페이스의 선언과 구현

인터페이스 선언

인터페이스를 선언할 때는 interface 키워드를 사용합니다. 인터페이스는 추상 메서드와 상수를 포함할 수 있습니다.

interface Vehicle {
    void start();
    void stop();
    int MAX_SPEED = 120; // 상수
}

인터페이스 구현

클래스는 implements 키워드를 사용하여 인터페이스를 구현합니다. 인터페이스의 모든 메서드를 구현해야 합니다.

class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car is starting");
    }

    @Override
    public void stop() {
        System.out.println("Car is stopping");
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.start(); // 출력: Car is starting
        myCar.stop();  // 출력: Car is stopping
    }
}

4. 인터페이스와 관련된 주요 키워드와 개념

default 메서드

자바 8부터 인터페이스는 default 메서드를 가질 수 있습니다. default 메서드는 기본 구현을 제공하며, 인터페이스를 구현하는 클래스에서 선택적으로 오버라이드할 수 있습니다.

interface Vehicle {
    void start();
    void stop();

    default void honk() {
        System.out.println("Honking...");
    }
}

class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car is starting");
    }

    @Override
    public void stop() {
        System.out.println("Car is stopping");
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.start(); // 출력: Car is starting
        myCar.honk();  // 출력: Honking...
        myCar.stop();  // 출력: Car is stopping
    }
}

static 메서드

자바 8부터 인터페이스는 static 메서드를 가질 수 있습니다. static 메서드는 인터페이스 자체에서 호출할 수 있습니다.

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

public class Main {
    public static void main(String[] args) {
        int result = MathUtils.add(5, 3);
        System.out.println("Result: " + result); // 출력: Result: 8
    }
}

private 메서드

자바 9부터 인터페이스는 private 메서드를 가질 수 있습니다. private 메서드는 인터페이스 내에서만 사용되며, default 메서드나 static 메서드에서 호출할 수 있습니다.

interface Vehicle {
    void start();
    void stop();

    default void service() {
        checkEngine();
        System.out.println("Servicing vehicle");
    }

    private void checkEngine() {
        System.out.println("Checking engine");
    }
}

class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car is starting");
    }

    @Override
    public void stop() {
        System.out.println("Car is stopping");
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.start();    // 출력: Car is starting
        myCar.service();  // 출력: Checking engine
                          // 출력: Servicing vehicle
        myCar.stop();     // 출력: Car is stopping
    }
}

5. 인터페이스와 추상 클래스의 차이점

특징인터페이스추상 클래스

다중 상속 지원 여부 지원 지원하지 않음
메서드 구현 기본적으로 구현 없음 (default 메서드 제외) 추상 메서드와 일반 메서드 모두 가질 수 있음
접근 제어자 public 모든 접근 제어자 사용 가능
인스턴스 변수 상수만 가질 수 있음 인스턴스 변수 가질 수 있음
생성자 없음 있음

결론

이 글에서는 자바의 인터페이스에 대해 자세히 살펴보았습니다. 인터페이스는 다형성을 지원하고, 코드의 유연성과 확장성을 높이며, 다중 상속의 대안으로 사용됩니다. 또한, 인터페이스는 클래스 간의 계약을 명확히 하여 코드의 일관성을 유지하는 데 중요한 역할을 합니다. 추가적인 질문이 있으면 언제든지 댓글로 남겨주세요!

반응형