아래의 내용은 java_grammer 레파지토리 C04Interface 디렉터리에 저장되어있는 내용을 정리함
인터페이스는 모든 메서드가 구현부 없이 선언만 존재하는 추상적 설계서임.
클래스가 어떤 동작을 반드시 구현해야 함을 강제하기 위한 ‘규약(명세)’ 역할을 하는 것임.
즉, 추상클래스보다 더 추상적인 구조이며, 모든 메서드가 abstract로 간주됨.
package C04Interface;
public interface C01AnimalInterface1 {
void makeSound(); // 구현부 없는 추상메서드
}
인터페이스의 모든 메서드는 자동으로 public abstract로 선언된 것과 동일하게 처리됨.
명시적으로 abstract를 붙이지 않아도 추상 메서드로 인식됨.
하나의 클래스가 여러 인터페이스를 동시에 구현할 수도 있음. (자바에서는 클래스의 다중 상속은 불가능하지만, 인터페이스는 허용함.)
package C04Interface;
public interface C01AnimalInterface2 {
void eat(String food);
}
인터페이스끼리는 extends를 통해 다중 상속이 가능함.
package C04Interface;
// interface 간에는 extends 가능
public interface C01AnimalInterface3 extends C01AnimalInterface1, C01AnimalInterface2 {
}
즉, C01AnimalInterface3는 상위 두 인터페이스의 모든 메서드를 물려받는 구조임.
자식 인터페이스를 구현하는 클래스는 상속받은 모든 추상 메서드를 구현해야 함.
클래스에서 인터페이스를 상속받을 때는 implements 키워드를 사용함.
package C04Interface;
public class C01Cat implements C01AnimalInterface1, C01AnimalInterface2 {
@Override
public void makeSound() {
System.out.println("야옹~야옹~");
}
@Override
public void eat(String food) {
System.out.println(food + "를 먹습니다.");
}
}
C01Cat 클래스는 C01AnimalInterface1과 C01AnimalInterface2를 모두 구현함.
따라서 두 인터페이스의 메서드 makeSound(), eat()를 반드시 재정의해야 하는 것임.
또 다른 예시로 C01Dog 클래스는 하나의 인터페이스만 구현하는 형태임.
package C04Interface;
public class C01Dog implements C01AnimalInterface1 {
@Override
public void makeSound() {
System.out.println("멍!멍!");
}
}
package C04Interface;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class C01InterfaceMain {
public static void main(String[] args) {
// 일반적인 객체 생성
C01Cat c1 = new C01Cat();
c1.makeSound();
C01Dog d1 = new C01Dog();
d1.makeSound();
/// ************ 인터페이스의 핵심 특징 ************ ///
// - 모든 메서드가 추상 메서드로 구성
// - 구조 : 인터페이스타입 객체명 = new 구현클래스타입();
// 다형성 예시
C01AnimalInterface1 c2 = new C01Cat();
c2.makeSound();
C01AnimalInterface1 d2 = new C01Dog();
d2.makeSound();
/// ************ 다형성의 장점 ************ ///
// 인터페이스를 부모 타입으로 쓰면,
// 구체 클래스(구현체)를 변경하더라도 코드를 수정하지 않아도 됨.
// 예: List 인터페이스 → 구현체 변경 (ArrayList ↔ LinkedList)
List<Integer> myList = new LinkedList<>();
myList.add(10);
myList.add(20);
myList.get(0);
/// ************ 다중 구현(상속) ************ ///
C01AnimalInterface1 c3 = new C01Cat();
c3.makeSound();
C01AnimalInterface2 c4 = new C01Cat();
c4.eat("츄르");
/// ************ 다형성 구조 예시 ************ ///
// List와 Queue 예시
List<Integer> myList1 = new LinkedList<>();
// myList1.get(0); // 가능함
Queue<Integer> myList2 = new LinkedList<>();
// myList2.get(0); // 불가능 - Queue에는 get 메서드 없음
// List는 인덱스 기반 구조이므로 get() 사용에 최적화되어 있음.
// Queue는 FIFO(First-In-First-Out) 구조이므로 get()은 비효율적임.
// 따라서 인터페이스를 어떻게 지정하느냐에 따라 사용 가능한 메서드가 달라지는 것임.
// LinkedList는 List와 Deque 인터페이스를 모두 구현함.
// Deque는 Queue를 상속받기 때문에 Queue형 참조도 가능함.
}
}
| 특징 | 설명 |
|---|---|
| 모든 메서드 | 자동으로 public abstract로 선언됨 |
| 변수 | 자동으로 public static final 상수로 선언됨 |
| 상속 관계 | 다중상속 가능 (extends) |
| 클래스 구현 | implements 키워드 사용 |
| 객체 생성 | 불가능 (구현 클래스 필요) |
| 목적 | 공통적인 기능 규약 정의 (다형성, 의존성 분리) |
다형성(polymorphism)의 핵심은, 인터페이스를 부모 타입으로 두고 여러 구현체를 동일한 타입으로 다룰 수 있다는 것임.
C01AnimalInterface1 a = new C01Cat();
a.makeSound();
a = new C01Dog();
a.makeSound();
위 코드에서 a는 C01AnimalInterface1 타입이지만, 실제 동작은 런타임 시점에 대입된 객체(Cat, Dog)에 따라 달라짐.
즉, 같은 인터페이스를 기반으로 다른 구현체의 동작을 일관된 방식으로 제어할 수 있게 되는 것임.
자바에서는 클래스의 다중 상속은 금지되어 있지만,
인터페이스는 다중 구현이 허용되어 있음.
public class C01Cat implements C01AnimalInterface1, C01AnimalInterface2 {
...
}
이를 통해 하나의 클래스가 여러 역할 또는 기능을 동시에 수행하도록 설계할 수 있음.
예를 들어 C01Cat은 ‘소리를 내는 동물’이면서 동시에 ‘먹이를 먹는 동물’ 역할도 가질 수 있음.
| 구분 | 추상클래스 | 인터페이스 |
|---|---|---|
| 키워드 | abstract | interface |
| 메서드 구성 | 일반메서드 + 추상메서드 | 전부 추상메서드 (기본값) |
| 필드 | 인스턴스 변수 가능 | 전부 상수(public static final) |
| 다중상속 | 불가능 | 가능 |
| 객체 생성 | 불가(상속 필요) | 불가(구현 필요) |
| 목적 | 공통된 기본 구조 제공 | 구현 강제, 다형성 확보 |