[Java] 추상 클래스(Abstract Class), 인터페이스(Interface)

wujin·2024년 1월 4일
post-thumbnail

Java에서 추상 클래스(Abstract)와 인터페이스(Interface)는 둘 다 추상화 하기 위한 도구이다. 하지만 각각의 특성과 사용법이 다르다.

추상 클래스(Abstract)

  1. 부분적 구현 제공

    • 추상 클래스는 추상 메서드뿐만 아니라 구현된 메서드도 포함할 수 있다. 이는 공통된 동작을 상속하는 서브 클래스들에게 제공된다. 따라서 추상 클래스는 부분적으로 구현된 클래스이다.
  2. 상속과 확장

    • 추상 클래스는 일반 클래스처럼 다른 클래스로부터 상속을 받아 확장될 수 있다. 추상 클래스를 상속받는 서브 클래스는 추상 메서드를 반드시 구현해야 한다.
  3. 단일 상속

    • Java는 단일 상속만을 지원한다. 따라서 추상 클래스는 단일 상속의 제약을 받는다.
  4. 구체 클래스 생성 불가

    • 추상 클래스는 직접 객체를 생성할 수 없다. 그러나 추상 클래스의 참조 변수를 사용하여 서브 클래스의 인스턴스를 참조할 수 있다.
// 추상 클래스 Animal 정의
abstract class Animal {
    // 구현되지 않은 추상 메서드
    abstract void makeSound();

    // 구현된 일반 메서드
    void move() {
        System.out.println("이동합니다.");
    }
}

// Animal을 상속받는 Dog 클래스 정의
class Dog extends Animal {
    // 추상 메서드 구현
    void makeSound() {
        System.out.println("멍멍");
    }
}

// Animal을 상속받는 Cat 클래스 정의
class Cat extends Animal {
    // 추상 메서드 구현
    void makeSound() {
        System.out.println("야옹");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.makeSound(); // "멍멍" 출력
        dog.move(); // "이동합니다." 출력

        Animal cat = new Cat();
        cat.makeSound(); // "야옹" 출력
        cat.move(); // "이동합니다." 출력
    }
}

인터페이스(Interface)

  1. 순수 추상화

    • 인터페이스는 추상 메서드만을 포함하며, 어떤 구현도 가지지 않는다. 이는 인터페이스를 순수한 추상화로 만든다.
  2. 다중 상속

    • 클래스는 여러 개의 인터페이스를 구햔할 수 있다. 이는 자바의 다중 상속을 대체하는 매커니즘으로, 클래스가 다양한 기능을 구현할 수 있게 해준다.
  3. 관련된 클래스 간의 계약

    • 인터페이스는 클래스 간의 규약(Contract)을 정의하는데 사용된다. 이는 인터페이스가 특정 메서드를 구현해야 한다는 약속이며, 이를 구현한 클래스는 해당 동작을 보장한다.
  4. 강한 결합도 제거

    • 인터페이스를 사용하면 클래스 간의 결합도를 낮출 수 있다. 클래스가 인터페이스를 구현함으로써, 클래스 간의 의존성을 최소화하고 코드의 재사용성을 높일 수 있다.
// 인터페이스 Vehicle 정의
interface Vehicle {
	// 추상 메서드
    void start();
    void stop();
}

// Car 클래스가 Vehicle 인터페이스를 구현
class Car implements Vehicle {
    // 인터페이스의 추상 메서드 구현
    public void start() {
        System.out.println("자동차 시동을 켭니다.");
    }

    public void stop() {
        System.out.println("자동차 시동을 끕니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        Vehicle car = new Car();
        car.start(); // "자동차 시동을 켭니다." 출력
        car.stop(); // "자동차 시동을 끕니다." 출력
    }
}

그래서

추상 클래스(Abstract)는 부분적인 구현을 제공하고, 하위 클래스에게 동작을 상속받도록 하며, 일반적으로 단일 상속을 지원한다.

반면에, 인터페이스(Interface)는 클래스 간의 규약을 정의하고, 다중 상속을 지원하여 클래스 간의 결합도를 낮춘다.

추상 클래스는 is-a 관계를 나타내는데 사용되고, 인터페이스는 has-a 관계를 나타내는데 사용된다.

is-a 관계는 상속 관계를 나타낸다.
A가 B를 상속받을 때, "A는 B이다"라고 표현할 수 있다. 이는 A가 B의 특정 형태이며, B의 모든 특성을 상속받는다는 의미이다. 이러한 관계는 주로 추상 클래스를 사용하여 나타내며, 상속을 통해 부모 클래스의 기능을 확장하거나 재사용하는 데 사용된다.
예를 들어, "개(Dog)는 동물(Animal)이다"라고 말할 수 있다. 이는 개 클래스가 동물 클래스를 상속받고 있으며, 동물 클래스의 특성을 가지고 있다는 것을 의미한다.

has-a 관계는 객체가 다른 객체를 포함하고 있음을 나타낸다.
A가 B를 포함하고 있을 때, "A는 B를 가지고 있다"라고 표현할 수 있다. 이는 A가 B의 일부를 포함하고 있지만, A와 B는 독립적인 개체이다. 이러한 관계는 주로 인터페이스를 사용하여 나타내며, 객체 간의 협력을 정의하는 데 사용된다.

0개의 댓글