Java에서 추상 클래스(Abstract)와 인터페이스(Interface)는 둘 다 추상화 하기 위한 도구이다. 하지만 각각의 특성과 사용법이 다르다.
부분적 구현 제공
상속과 확장
단일 상속
구체 클래스 생성 불가
// 추상 클래스 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(); // "이동합니다." 출력
}
}
순수 추상화
다중 상속
관련된 클래스 간의 계약
강한 결합도 제거
// 인터페이스 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는 독립적인 개체이다. 이러한 관계는 주로 인터페이스를 사용하여 나타내며, 객체 간의 협력을 정의하는 데 사용된다.