ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] 인터페이스
    언어/Java 2021. 1. 10. 19:07

    인터페이스는 객체의 사용 방법을 정의한 타입입니다. 인터페이스를 통해 다양한 객체를 동일한 사용 방법으로 이용할 수 있습니다.


    인터페이스는 개발 코드와 객체가 서로 통신하는 접점 역할을 합니다. 개발 코드가 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출시킵니다. 그렇게 때문에 개발 코드는 객체의 내부 구조를 알 필요가 없고 인터페이스의 메소드만 알고 있으면 됩니다.

    • 개발 코드가 직접 객체의 메소드를 호출하면 간단한데 왜 중간에 인터페이스를 둘까?
      • 개발 코드를 수정하지 않고 사용하는 객체를 변경할 수 있도록 하기 위해서입니다. 인터페이스는 하나의 객체가 아니라 여러 객체들과 사용하므로 어떤 객체를 사용하느냐에 따라서 실행 내용과 리턴 값이 다를 수 있습니다. 따라서 개발 코드 측면에서는 코드 변경 없이 실행 내용과 리턴 값을 다양하게 쓸 수 있습니다.


    인터페이스는 클래스 대신 interface 키워드를 사용합니다. 또한 상수 필드와 추상 메소드만 작성할 수 있고 객체를 생성할 수 없기 때문에 생성자를 가질 수 없습니다.

    상수 필드 선언

    인터페이스는 객체 사용 방법을 정의한 것이므로 실행시 데이터를 저장할 수 있는 인스턴스 또는 정적 필드를 선언할 수 없습니다. 그러나 상수 필드는 선언이 가능합니다. 해당 상수는 인터페이스에 고정된 값이므로 실행 시에 데이터를 바꿀 수 없습니다. 인터페이스에서 선언된 필드는 모두 public static final 특성을 갖고 있으며 생략하더라도 컴파일 과정에서 자동으로 붙습니다.

    상수 이름은 대문자로 작성하고 다른 문자와 연결할 시, 언더바로 연결합니다.

    public interface Control {
        public int VOLUME = 10;
        int VOLUME1 = 10;
    }

    추상 메소드 선언

    인터페이스를 통해 호출된 메소드는 최종적으로 객체에서 실행됩니다. 따라서 인터페이스의 메소드는 실행 블록이 필요 없는 추상 메소드로 선언합니다. 인터페이스에 선언된 추상 메소드는 모두 public abstract의 특성을 갖기 때문에 public abstract를 생략하더라도 컴파일 과정에서 자동으로 붙습니다.

    public interface Control {
        public int VOLUME = 10;
        
        public void turnOn();
        public void turnOff();
        public void setVolume(int volume);
    }

    구현

    개발 코드가 인터페이스 메소드를 호출하면 인터페이스는 객체의 메소드를 호출합니다. 객체는 인터페이스에서 정의된 추상 메소드와 동일한 메소드 이름, 매개 타입, 리턴 타입을 가진 실체 메소드를 가지고 있어야 합니다. 이러한 객체를 인터페이스의 구현 객체라 하고 구현 객체를 생성하는 클래스를 구현 클래스라고 합니다.

    구현 클래스

    구현 클래스는 보통의 클래스와 동일한데 인터페이스 타입으로 사용할 수 있음을 알려주기 위해 클래스 선언부에 implements 키워드를 추가합니다.

    public class Phone implements Control{
        private int volume;
    
        @Override
        public void turnOn() {
            System.out.println("turn On");
        }
    
        @Override
        public void turnOff() {
            System.out.println("turn Off");
        }
    
        @Override
        public void setVolume(int volume) {
            if (volume > Control.MAX_VOLUME) {
                this.volume = Control.MAX_VOLUME;
            } else {
                this.volume += volume;
            }
    
            System.out.println(this.volume);
        }
    }


    구현 클래스에서 인터페이스의 추상 메소드에 대한 실체 메소드를 작성할 때 public보다 낮은 접근 제한을 작성할 수 없습니다.

    구현클래스가 작성되면 new 연산자로 객체를 생성할 수 있습니다. 아래의 코드는 인터페이스를 사용한 것이 아닌 케이스 입니다.

    Phone phone = new Phone();


    인터페이스로 구현 객체를 사용하려면 다음과 같이 인터페이스 변수를 선언하고 구현 객체를 대입해야 합니다. 인터페이스 변수는 참조 타입이기 때문에 국현 객체가 대입될 경우 구현 객체의 번지를 저장합니다.

    Control p = new Phone();
    
    p.turnOn();
    p.turnOff();
    
    Control p2;
    p2 = new Phone;

    다중 인터페이스 구현 클래스


    public interface Search {
        void search(String uri);
    }
    
    
    public class Phone implements Control, Search {
        private int volume;
    
        @Override
        public void turnOn() {
            System.out.println("turn On");
        }
    
        @Override
        public void turnOff() {
            System.out.println("turn Off");
        }
    
        @Override
        public void setVolume(int volume) {
            if (volume > Control.MAX_VOLUME) {
                this.volume = Control.MAX_VOLUME;
            } else {
                this.volume += volume;
            }
    
            System.out.println(this.volume);
        }
    
        @Override
        public void search(String uri) {
            System.out.println(uri);
        }
    }
    
    
    Phone phone = new Phone();
    
    Control controlPhone = phone;
    Search searchPhone = phone;
    
    controlPhone.turnOn();
    searchPhone.search("naver");

    사용

    public class MyClass {
        // 기본
        Control c = new Phone();
    
        MyClass() {}
        // 생성자에서 받음
        MyClass(Control c) {
            this.c = c;
        }
    
        void changeDevice(Control c) {
            System.out.println("Changedevice");
            c.turnOn();
            c.setVolume(5);
        }
    }
    
    
    MyClass m1 = new MyClass();
    m1.c.turnOn();
    m1.c.setVolume(2);
    
    MyClass m2 = new MyClass(new SmartPhone());
    m2.c.turnOn();
    
    MyClass m3 = new MyClass();
    m3.c.turnOn();
    m3.c.setVolume(2);
    m3.changeDevice(new SmartPhone());
    
    
    
    // turn On
    // 2
    // smartphone turn On
    // turn On
    // 2
    // Changedevice
    // smartphone turn On
    // 5


    댓글