
인터페이스는 설계 표준입니다.
즉, 클래스가 따라야 할 최소한의 공통 규칙을 정의하는 역할을 합니다.
모든 설계에는 표준이 필요한 것처럼, 프로그래밍에서도 인터페이스를 사용하여 코드의 일관성을 유지할 수 있습니다.
만약 개발자마다 서로 다른 방식으로 메서드를 만든다면, 코드의 가독성이 떨어지고 유지보수가 어려워질 수 있습니다.
인터페이스를 활용하면 최소한의 규격을 정의할 수 있고, 세부 구현은 각 클래스에서 자유롭게 할 수 있습니다.
즉, 일관성을 유지하면서도 각 클래스가 고유한 특성을 확장할 수 있도록 돕습니다.
class LuxuryCar {
void move() {
System.out.println("멋지게 이동합니다.");
}
void stop() {
System.out.println("멋지게 정지합니다.");
}
}
class SpeedCar {
void drive() {
System.out.println("빠르게 주행합니다.");
}
}
public class Main {
public static void main(String[] args) {
LuxuryCar car1 = new LuxuryCar();
SpeedCar car2 = new SpeedCar();
car1.move(); // ❌ 일관되지 않은 주행 명령어
car1.stop();
car2.drive(); // ❌ 일관되지 않은 주행 명령어 + 멈출 수 없음
}
}
위 코드에서는 LuxuryCar와 SpeedCar가 서로 다른 방식으로 주행을 수행해야 합니다. 이는 같은 자동차임에도 불구하고 메서드 이름이 다르다는 문제를 발생시킵니다.
인터페이스를 적용하면 일관된 방식으로 기능을 구현할 수 있습니다.
interface Car {
void drive();
void stop();
}
class LuxuryCar implements Car {
@Override
public void drive() {
System.out.println("멋지게 이동합니다.");
}
@Override
public void stop() {
System.out.println("멋지게 정지합니다.");
}
void charge() {
System.out.println("차량을 충전합니다.");
}
}
class SpeedCar implements Car {
@Override
public void drive() {
System.out.println("빠르게 이동합니다.");
}
@Override
public void stop() {
System.out.println("빠르게 정지합니다.");
}
void autoParking() {
System.out.println("자동 주차 기능을 실행합니다.");
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new LuxuryCar();
Car car2 = new SpeedCar();
car1.drive();
car1.stop();
car2.drive();
car2.stop();
}
}
한 클래스가 여러 인터페이스를 구현할 수 있습니다.
interface Animal {
void eat();
}
interface Flyable {
void fly();
}
class Bird implements Animal, Flyable {
@Override
public void eat() {
System.out.println("새가 먹이를 먹습니다.");
}
@Override
public void fly() {
System.out.println("새가 하늘을 납니다.");
}
public void land() {
System.out.println("새가 착륙합니다.");
}
}
public class Main {
public static void main(String[] args) {
Bird bird = new Bird();
bird.eat();
bird.fly();
bird.land();
}
}
인터페이스는 다중 상속이 가능합니다.
interface Animal {
void eat();
}
interface Flyable {
void fly();
}
interface FlyableAnimal extends Animal, Flyable {
void land();
}
class Bird implements FlyableAnimal {
@Override
public void eat() {
System.out.println("새가 먹이를 먹습니다.");
}
@Override
public void fly() {
System.out.println("새가 하늘을 납니다.");
}
@Override
public void land() {
System.out.println("새가 착륙합니다.");
}
}
public class Main {
public static void main(String[] args) {
Bird bird = new Bird();
bird.eat();
bird.fly();
bird.land();
}
}
인터페이스에서 변수를 선언하면 자동으로 public static final이 적용됩니다.
public interface Config {
int POPULATION = 100; // 자동으로 public static final 적용됨
}
public class Main {
public static void main(String[] args) {
System.out.println(Config.POPULATION);
}
}
인터페이스를 활용하면 코드의 일관성을 유지하고, 확장성을 높일 수 있습니다. 이를 통해 개발자 간 협업이 수월해지고 유지보수가 쉬워집니다.