
이 내용은 Backend/OOP logic in Java 영역(객체지향 설계)에서 다형성과 구조 분리를 위해 사용하는 핵심 개념이다. 인터페이스는 클래스가 “반드시 구현해야 하는 메서드들의 집합”을 정의하는 일종의 규약(Protocol)이다.
Java에서 인터페이스는 클래스가 구현해야만 하는 메서드들의 집합을 정의하는 구조이다. 즉, “이 클래스를 사용하려면 이 기능들은 반드시 제공해야 한다”는 약속(Contract)을 코드로 표현한 것이다.
인터페이스는 메서드의 시그니처(메서드명, 리턴 타입, 매개변수)만 정의하며, 메서드의 실제 구현은 포함하지 않는다. → 모든 메서드는 기본적으로 추상 메서드
public static final 상수implements) 가능public추상 클래스는 단일 상속만 가능하지만, 인터페이스는 여러 개를 동시에 구현할 수 있기 때문에 구조 설계가 훨씬 유연해진다.
| 구분 | 추상 클래스 | 인터페이스 |
|---|---|---|
| 메서드 | 일반 메서드 + 추상 메서드 | 기본적으로 모두 추상 메서드 |
| 필드(field) | 인스턴스 변수 가능 | 상수만 가능 (public static final) |
| 상속/구현 | 단일 상속(extends) | 다중 구현(implements) |
| 생성자 | 가질 수 있음 | 가질 수 없음 |
| 상태 저장 | 가능 | 불가능 |
즉, 추상 클래스는 “부분 구현 + 상태 저장”이 가능하고, 인터페이스는 “완전한 추상화 + 다중 구현”이 핵심이다.
public abstract class Person {
private String name;
public Person(String name) {
this.name = name;
}
public abstract void introduce();
}
public class Student extends Person {
private String school;
public Student(String name, String school) {
super(name);
this.school = school;
}
@Override
public void introduce() {
System.out.println("My name is " + name + " from " + school);
}
}
여기서 알 수 있는 점은: 추상 클래스는 객체 생성을 직접 못하더라도, 생성자를 통해 자식 클래스의 객체 생성 방식까지 통제할 수 있다는 것이다.
인터페이스는 필드(상태)를 가질 수 없고, 메서드 구현도 없다. (Java 8 이후 default, static 메서드가 추가되었지만, 기본 구조는 동일)
public interface Up {
void onUp();
}
public interface Press {
void onPressed();
}
public interface Down {
void onDown();
}
위 인터페이스들은 “버튼이 가져야 할 동작 규약”만 정의한다.
public abstract class Button implements Down, Up, Press {
@Override
public void onDown() {}
@Override
public abstract void onPressed();
@Override
public void onUp() {}
}
여기서 핵심 포인트:
public class PowerButton extends Button {
private boolean status;
@Override
public void onPressed() {
if (status) {
status = false;
System.out.println("전원을 끕니다.");
} else {
status = true;
System.out.println("전원을 켭니다.");
}
}
}
public class ChannelDownButton extends Button {
@Override
public void onDown() {
System.out.println("채널을 한 칸 내립니다.");
}
@Override
public void onPressed() {
System.out.println("채널을 계속 내립니다.");
}
}
public class VolumeDownButton extends Button {
@Override
public void onDown() {
System.out.println("볼륨을 한 칸 내립니다.");
}
@Override
public void onPressed() {
System.out.println("볼륨을 계속 내립니다.");
}
}
public class VolumeUpButton extends Button {
@Override
public void onUp() {
System.out.println("볼륨을 한 칸 올립니다.");
}
@Override
public void onPressed() {
System.out.println("볼륨을 계속 올립니다.");
}
}
public class TvRemoteController {
private PowerButton powerButton;
private ChannelDownButton channelDownButton;
private ChannelUpBotton channelUpBotton;
private VolumeUpButton volumeUpButton;
private VolumeDownButton volumeDownButton;
public TvRemoteController(PowerButton powerButton, ChannelDownButton channelDownButton,
ChannelUpBotton channelUpBotton, VolumeUpButton volumeUpButton,
VolumeDownButton volumeDownButton) {
this.powerButton = powerButton;
this.channelDownButton = channelDownButton;
this.channelUpBotton = channelUpBotton;
this.volumeUpButton = volumeUpButton;
this.volumeDownButton = volumeDownButton;
System.out.println("Tv 리모컨 객체가 생성되었습니다.");
}
public void onPressedPowerButton() {
powerButton.onPressed();
}
public void onPressedChannelDownButton() {
channelDownButton.onPressed();
}
public void onDownChannelDownButton() {
channelDownButton.onDown();
}
public void onPressedChannelUpButton() {
channelUpBotton.onPressed();
}
public void onUpChannelUpButton() {
channelUpBotton.onUp();
}
public void onPressedVolumeDownButton() {
volumeDownButton.onPressed();
}
public void onDonwVolumeDownButton() {
volumeDownButton.onDown();
}
public void onPressedVolumeUpButton() {
volumeUpButton.onPressed();
}
public void onUpVolumeUpButton() {
volumeUpButton.onUp();
}
}
public class Main {
public static void main(String[] args) {
TvRemoteController tvRemoteController = new TvRemoteController(
new PowerButton(),
new ChannelDownButton(),
new ChannelUpBotton(),
new VolumeUpButton(),
new VolumeDownButton()
);
tvRemoteController.onPressedPowerButton();
tvRemoteController.onPressedChannelDownButton();
tvRemoteController.onDownChannelDownButton();
tvRemoteController.onPressedChannelUpButton();
tvRemoteController.onUpChannelUpButton();
tvRemoteController.onPressedVolumeDownButton();
tvRemoteController.onDonwVolumeDownButton();
tvRemoteController.onPressedVolumeUpButton();
tvRemoteController.onUpVolumeUpButton();
}
}
이 구조의 핵심은:
인터페이스는 “클래스가 반드시 제공해야 할 기능의 규약”을 정의하는 완전한 추상화 도구다. 필드(상태)를 가질 수 없고, 메서드 구현도 없으며, 대신 다중 구현이 가능해 확장성과 구조 분리에 매우 유리하다.
추상 클래스가 “공통 구현 + 일부 강제”라면, 인터페이스는 “규칙만 정의 + 전면 강제”라고 이해하면 가장 명확하다.