인터페이스(Interface)와 추상 클래스(Abstract Class)는 객체지향 프로그래밍에서 중요한 개념으로, 둘 다 상속을 통해 클래스 간의 관계를 정의하는 데 사용됩니다. 하지만 이 둘은 목적과 사용 방식에서 큰 차이가 있습니다. 아래에서 이 차이점을 설명하겠습니다.
1. 인터페이스 (Interface)
정의
- 인터페이스는 클래스가 반드시 구현해야 하는 메서드의 집합을 정의하는 것입니다.
- 인터페이스는 메서드 시그니처만 정의하고, 메서드의 실제 구현은 포함하지 않습니다.
- 인터페이스에는 일반적으로 추상 메서드만 포함되며, 모든 메서드는 암묵적으로 public이고abstract입니다.
- Java 8 이후부터는 인터페이스에 디폴트 메서드(default method)와 정적 메서드(static method)를 포함할 수 있게 되었습니다. 디폴트 메서드는 기본 구현을 제공하지만, 여전히 추상 메서드와 다릅니다.
사용 목적
- 행동의 계약을 정의하기 위해 사용됩니다. 인터페이스는 클래스를 특정한 방식으로 행동하게 하는 계약을 강제합니다.
- 다양한 클래스가 공통의 기능을 공유할 수 있도록 하며, 이러한 기능은 서로 관련이 없을 수도 있습니다.
예제
interface Flyable {
    void fly();
}
class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("Bird is flying");
    }
}
class Airplane implements Flyable {
    @Override
    public void fly() {
        System.out.println("Airplane is flying");
    }
}
- 위 예제에서 Flyable인터페이스는fly()메서드를 정의합니다.Bird와Airplane클래스는 이 인터페이스를 구현하면서 각자 다르게fly()메서드를 구현할 수 있습니다.
2. 추상 클래스 (Abstract Class)
정의
- 추상 클래스는 일부 메서드는 구현되지 않은 상태로 남겨두고, 다른 메서드는 구현된 상태로 제공할 수 있는 클래스입니다.
- 추상 클래스는 일반 클래스와 같이 인스턴스화할 수 없으며, 반드시 다른 클래스에서 상속받아 사용해야 합니다.
- 추상 클래스에는 추상 메서드(구현되지 않은 메서드)와 일반 메서드(구현된 메서드)를 함께 포함할 수 있습니다.
- 일반 변수와 메서드도 포함할 수 있습니다.
사용 목적
- 공통의 속성과 행동을 정의하기 위해 사용됩니다. 추상 클래스는 관련된 클래스들 간에 공통적으로 사용되는 메서드나 변수를 정의할 수 있습니다.
- 기본 구현을 제공하면서, 하위 클래스에서 필요한 부분을 재정의(override)하도록 할 수 있습니다.
예제
abstract class Animal {
    abstract void makeSound();
    void sleep() {
        System.out.println("Animal is sleeping");
    }
}
class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Dog barks");
    }
}
class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Cat meows");
    }
}
- 위 예제에서 Animal추상 클래스는makeSound()라는 추상 메서드를 정의합니다.Dog와Cat클래스는 이 메서드를 각각 재정의합니다. 추상 클래스는 또한sleep()과 같이 구현된 메서드를 포함할 수 있습니다.
3. 주요 차이점
| 특징 | 인터페이스 (Interface) | 추상 클래스 (Abstract Class) | 
| 구현 여부 | 모든 메서드는 추상적이며 구현되지 않습니다. | 추상 메서드와 구현된 메서드를 모두 포함할 수 있습니다. | 
| 상속 | 다중 상속 가능 (여러 인터페이스를 구현할 수 있음) | 단일 상속만 가능 (하나의 추상 클래스를 상속받을 수 있음) | 
| 변수 포함 여부 | 상수 ( static final)만 포함할 수 있습니다. | 일반 변수와 상수를 포함할 수 있습니다. | 
| 목적 | 행동을 정의하고, 클래스 간의 계약을 규정합니다. | 공통적인 속성이나 행동을 공유하며 기본 구현을 제공합니다. | 
| 접근 제어자 | 모든 메서드는 암묵적으로  public입니다. | 다양한 접근 제어자( public,protected,private)를 사용할 수 있습니다. | 
| 사용 시점 | 관련 없는 클래스가 동일한 행동을 수행해야 할 때 | 관련 클래스들이 공통적인 기능을 공유해야 할 때 | 
| Java 8 이후의 변화 | 디폴트 메서드와 정적 메서드 지원 | 기존 방식 그대로 | 
4. 사용 상황 예시
1) 인터페이스를 사용하는 상황:
- 예를 들어, 다양한 종류의 전자기기들이 충전 기능을 가져야 할 때, Chargeable인터페이스를 정의합니다. 각 전자기기는 이 인터페이스를 구현하여 충전 기능을 제공하게 됩니다.
- 여기서 전자기기들이 서로 관련이 없을 수도 있습니다. 예를 들어, 휴대폰, 전기차, 노트북이 각각 다른 충전 방식을 가지고 있어도, Chargeable인터페이스를 통해 "충전 가능"이라는 계약을 따르게 됩니다.
2) 추상 클래스를 사용하는 상황:
- 동물 클래스가 있고, 모든 동물이 잠을 자는 공통된 행동을 가진다고 가정합니다. 그러나 동물이 소리를 내는 방식은 다를 수 있습니다. 이 경우, Animal이라는 추상 클래스를 만들고, 공통된 행동(잠자기)은 이 클래스에서 구현하고, 소리를 내는 행동은 각 동물의 하위 클래스에서 구현하도록 합니다.
- 이렇게 하면 코드의 재사용성이 높아지고, 중복을 줄일 수 있습니다.
결론
- 인터페이스는 다양한 클래스가 동일한 행동을 구현하도록 강제할 때 사용됩니다. 이를 통해 서로 관련 없는 클래스들이 공통된 행동을 가질 수 있습니다.
- 추상 클래스는 관련된 클래스들 간에 공통된 속성과 행동을 공유하게 하고, 일부는 구체적인 하위 클래스에서 구현하도록 유도할 때 사용됩니다.
이 두 개념을 잘 이해하면 객체지향 설계에서 더 유연하고 재사용 가능한 코드를 작성하는 데 큰 도움이 됩니다.
Share article