JAVA/JAVA

Java | Interface

pathas 2020. 2. 3. 22:27

Interface 인터페이스

클래스 혹은 프로그램이 제공하는 기능을 명시적으로 선언하는 역할


특징

  1. 추상클래스와 동일하게 설계 목적으로 사용
  2. 멤버변수: 상수만 가능, static final을 이용해서 정적 상수 선언
    (static final)을 작성하지 않아도 자동으로 설정됨
  3. 추상메소드만 선언 가능, 일반메소드 사용 X ↔ 추상 클래스
    추상메소드만 사용하기 때문에 abstract 예약어 사용 X(써도 되긴 함)
  4. 인터페이스 간 상속 가능
  5. 인터페이스를 상속받은 자식 클래스는
    반드시 인터페이스의 추상메소드를 오버라이딩해야 함
    강제성, 통일성 부여
  6. 구현된 코드가 없기 때문에 객체를 생성할 수 없음
  7. 다형성을 지원하는 방법 중 하나

※ 전체 프로그램의 설계도 역할, 둘 이상의 클래스에 통일성을 부여함


추상 클래스와의 차이점

인터페이스 추상 클래스
다중 상속 가능
완전한 다중 상속 X
implements(구현) 필요
단일 상속만 가능
추상메소드만 작성 일반메소드도 사용 가능

implements : 인터페이스로부터 상속받은 추상 메소드를
클래스에서 일반 메소드로 오버라이딩해서 기능을 부여하는 것


형식

접근 제어자 interface 인터페이스명{
    // 상수
    접근 제어자 [static final] 자료형 변수명;
    // 추상 메소드, 구현부{} X
    public [abstract] 반환형 메소드명();
}

상속 형식

인터페이스 → 인터페이스

interface 자식 인터페이스명 extends 부모 인터페이스명 {}

클래스 → 인터페이스

// 단일 상속
class 클래스명 implements 인터페이스명 {}

// 다중 상속
class 클래스명 implements 인터페이스명1, 인터페이스명2 {}

클래스 → 클래스 & 인터페이스

// 클래스 하나와 여러 개의 인터페이스 상속
class 클래스명 extends 클래스명 implements 인터페이스명1, 인터페이스명2 {}

※ 주요 기능은 부모 클래스에 작성해 두고 부족한 부분을 인터페이스를 상속해서 채움


사용례

여러 개의 음향 기기에서 공통적으로 필요한 음악 재생 프로그램 설계

Volume.java

Volume 인터페이스 작성

package j200203;
// 전체 프로그램의 설계도, 모든 클래스에서 공통으로 필요로하는 메소드 선언

public interface Volume {
    // 1. 볼륨 증가, 수정 목적(매개변수 O, 반환값 X)
    public void volumeUp(int level);

    // 2. 볼륨 감소
    public void volumeDown(int level);

    // 3, 4 turn on, turn off
    // => 자식 인터페이스에서 구현
}

AdvanceVolume.java

volume 인터페이스를 상속하는 AdvanceVolume 인터페이스 작성

package j200203;

public interface AdvanceVolume extends Volume {

    // 프로그램 실행
    public void turnOn();

    // 프로그램 종료
    public void turnOff();
}

※ 프로그램 규모가 커지면 하나의 인터페이스에 모든 기능을 작성할 수 없기 때문에
여러 개의 인터페이스로 분할해서 기능별로 관리함


TV.java

AdvanceVolume 인터페이스를 상속하는 TV 클래스 작성

package j200203;

public class TV implements AdvanceVolume {
    // 멤버 변수 선언, 기본 볼륨 설정
    private int volLevel;

    // 1. 볼륨 증가 메소드 오버라이딩
    public void volumeUp(int level) {
        volLevel += level;
        System.out.println("볼륨이 " + level + "만큼 증가했습니다.");
        System.out.println("현재 볼륨: " + volLevel);
    }

    // 2. 볼륨 감소 메소드 오버라이딩
    public void volumeDown(int level) {
        if (volLevel - level < 0) {
            System.out.println("볼륨의 크기는 0보다 작을 수 없습니다!");
            System.out.println("현재 볼륨: " + volLevel);
        }
        else {
            volLevel -= level;
            System.out.println("볼륨이 " + level + "만큼 감소했습니다.");
            System.out.println("현재 볼륨: " + volLevel);
        }
    }

    // 3. 전원 켜기 메소드 오버라이딩
    public void turnOn() {
        // 전원을 켰을 때 기본 볼륨을 10으로 설정
        volLevel = 10;
        System.out.println("TV 전원이 켜졌습니다.");
    }

    // 4. 전원 끄기 메소드 오버라이딩
    public void turnOff() {
        System.out.println("TV 전원이 꺼졌습니다.");
    }

}

※ TV 클래스와 유사한 Radio, Mp3, Speaker,,,, 등의 여러 가지 클래스를
간단한 수정만을 통해서 유사하게 작성할 수 있음


VolTest.java

TV 클래스와 그와 유사한 Radio 클래스를 객체화해서 실행

package j200203;

public class VolTest {

    public static void main(String[] args) {
         // TV 클래스 객체화
        TV tv = new TV();
        tv.turnOn();
        tv.volumeUp(3);
        tv.volumeDown(5);
        tv.turnOff();

        System.out.println("=======================");

         // Radio 클래스 객체화
        Radio rd = new Radio();
        rd.turnOn();
        rd.volumeUp(5);
        rd.volumeDown(20);
        rd.turnOff();

        // 객체는 다 다르지만 공통으로 사용하는
        // 메소드의 형식 및 이름은 동일하며 세부적인 기능(구현부)만 다름
        // => 다형성

    }

}

사용례_인터페이스 & 추상 클래스 활용

도형(원, 사각형, 삼각형,,,)에 따른 면적을 구하고, 그림을 그리는 프로그램 작성

Shape.java

추상 클래스
면적을 구하는 추상 메소드 명시
면적 멤버 변수, 면적을 출력하는 일반 메소드 작성

package j200203;

public abstract class Shape {

    // 면적을 저장할 멤버 변수, 모든 도형에 공통으로 적용
    public double res = 0.0;

    // =========== 추상 메소드 ===========
    // 원 면적 구하기, 반지름을 매개변수로 받는 메소드를 자식 클래스에서 구현
    public abstract double areaCircle(int r);

    // 직사각형
    abstract public double areaSquare(int w, int h);

    // =========== 일반 메소드 ===========
    // 면적 출력 메소드
    public void printArea() {
        System.out.println("도형의 면적은 " + res + "입니다.");
    }
}

Drawable.java

도형을 그리는 메소드를 명시하는 인터페이스

package j200203;

public interface Drawable {
    public void draw(); // abstract가 생략되어 있음

}

ShapeTest.java

추상 메소드 구현(오버라이딩) 및 프로그램 실행

package j200203;

// Shape 클래스와 Drawable 인터페이스 상속
public class ShapeTest extends Shape implements Drawable {

    // 원의 면적을 구하는 메소드 오버라이딩
    public double areaCircle(int r) {
        return r * r * Math.PI;
    }

    // 사각형의 면적을 구하는 메소드 오버라이딩
    public double areaSquare(int w, int h) {
        res = w * h;
        return res;
    }

    // 그림을 그리는 메소드 오버라이딩
    public void draw() {
        System.out.println("원, 직사각형 그림을 그립니다.");
    }

    public static void main(String[] args) {

        ShapeTest st = new ShapeTest();

        double ac = st.areaCircle(3);
        System.out.println("원 면적: " + ac);

        double sc = st.areaSquare(2, 5);
        System.out.println("사각형 면적: " + sc);

        st.draw();
    }
        /*
        원 면적: 28.274333882308138
        사각형 면적: 10.0
        원, 직사각형 그림을 그립니다.
        */        
}

프로그램을 전체적으로 설계할 때 사용하는 인터페이스에 대해 알아보았습니다.

추상클래스는 일반메소드도 작성할 수 있으면서 단일 상속만 가능하지만,

인터페이스는 상수와 추상메소드만 작성할 수 있고 다중 상속이 가능하다는 것이 가장 큰 차이점입니다.

인터페이스는 클래스의 부족한 부분을 채우기 위해서도 사용할 수 있고,

전체적인 설계를 위해서도 사용할 수 있기 때문에 상황에 맞게 적절하게 사용해야겠습니다.