article thumbnail image
Published 2022. 6. 24. 23:27

 

 

인터페이스(Interface)

 

 

인터페이스는 하나의 추상적 개념이다. 가령 자동차를 예시로 들어보자. 자동차의 사전 뜻은 다음과 같다.

자동차 (自動車) 
[명사]
 
원동기를 장치하여 그 동력으로 바퀴를 굴려서 철길이나 가설된 선에 의하지 아니하고 땅 위를 움직이도록 만든 차. 승용차, 승합자동차, 화물자동차, 특수자동차 및 이륜자동차가 있다.

그렇다. 자동차는 결국 여러 부품들이 들어가 사람이 타고다닐 수 있도록 만들어진 것을 뜻한다.

그것을 통상적으로 자동차라 부르며, 이를 구성하는 부품들과 바퀴와 좌석의 개수 등에 따라 얼마든지 다양한 형태로 존재할 수 있다. 추상적이라는 건 결국 껍데기라고 생각해도 무방할 것 같다.

 

인터페이스도 마찬가지다.

인터페이스 안에 여러 상수와 메서드를 선언하고, 이를 implements하는 클래스들에게 지원해준다.

그리고 필요할 때마다 메서드를 따로 생성하는 불편함 없이 implements한 클래스를 가져와서 쓰면 되는것이다.

 

또한, 인터페이스의 가장 큰 특징 중 하나는, 부모클래스를 상속받는 자식클래스 경우와 다르게,

다중으로 implements를 받을 수 있다.

 

그럼 지금부터 인터페이스를 선언하는 방법을 알아보겠다.

Interface 클래스명으로 시작한다.

interface Car {

    double discount = 0.1;
    void Speed(int gear);
    void Handle(int handleSize);
    void Wheel(int wheelCount);
    void Price(int price);

    default void Score(int score) {
        System.out.println("자동차의 점수는 " + score + "점입니다.");
    }

    static void Test(String carName) {
        System.out.println(carName + " 자동차가 정상인지 검사를 진행합니다.");
    }
}

먼저, 정의 방식에는 4가지가 있다.

1. 기본타입의 상수: 기본 값을 정의한다.

  • 기본 상수의 경우는 implements하는 클래스에서는 바꿀 수 없다. 그냥 바꾸지 말라는 소리다.

2. 추상메서드: 반환타입 + 메서드명(매개변수)

  • 추상메서드는 오바라이딩 해서 입맛대로 재구현하면 된다. implements하는 순간 필수로 사용해야한다.

3. 디폴트 메서드: default + 반환타입 + 메서드명(매개변수)

  • 디폴트 메서드는 사용 여부에 대해 선택할 수 있다는 점에서 추상메서드와 다르다.

4. 정적메서드: static + 반환타입 + 메서드명(매개변수)

  • 정적메서드는 오버라이딩 할 수 없다. 그냥 가져다 써야한다.

 

이제 implement부터 오버라이딩까지 해보겠다.

class Sedan implements Car {

    int gear;
    int handleCount;
    int wheelCount;
    int price;

    @Override
    public void Speed(int gear) {
        this.gear = gear;
        System.out.println("최대 속도는 " + gear * 50 + "입니다.");
    }

    @Override
    public void Handle(int handleSize) {
        this.handleCount = handleSize;
        System.out.println("핸들 사이즈는 " + handleSize + "입니다.");
    }

    @Override
    public void Wheel(int wheelCount) {
        this.wheelCount = wheelCount;
        System.out.println("바퀴의 개수는 " + wheelCount + "입니다.");
    }

    @Override
    public void Price(int price) {
        this.price = price;

        System.out.println("자동차의 가격은 " + price * (1-discount) + "원입니다.");
    }
}

처음에 설명한 것처럼 자동차는 기본적으로 공통으로 갖는 요소들이 있다.

가령 여러 회사에 자동차를 납품해야한다고 가정했을 때, 필수 요소들을 추상메서드로 갖는 동일한 규격의 인터페이스를 가져와 각 회사에 맞는 클래스를 만들면 된다.

또한, 특정 회사에만 특정 요소들이 추가됐을 때는 디폴트 메서드를 만들어서 유연하게 대처할 수 있다.

지금은 Sedan 하나의 클래스만 만들었지만, 얼마든지 여러 종류의 차들을 클래스로 만들어 적용시킨다면 확실히 데이터를 관리하기 편할것이다.

 

그럼 마지막으로 위에서 작성한 코드를 출력해보겠다.

public class Note {
    public static void main(String[] args) {

        Car sedan = new Sedan();
        sedan.Speed(5);
        sedan.Handle(20);
        sedan.Wheel(4);
        sedan.Price(10000000);
        sedan.Score(100);
        Car.Test("Sedan");
    }
}
최대 속도는 250입니다.
핸들 사이즈는 20입니다.
바퀴의 개수는 4입니다.
자동차의 가격은 9000000.0원입니다.
자동차의 점수는 100점입니다.
Sedan 자동차가 정상인지 검사를 진행합니다.
복사했습니다!