ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이것이 자바다 | 8장 인터페이스
    JAVA/이것이 자바다 2022. 7. 10. 15:18

    인터페이스

     

    • 인터페이스의 역할: 개발 코드와 객체가 서로 통신하는 접점 역할
    • 개발 코드 -> 인터페이스의 메소드 => 인터페이스 -> 객체의 메소드 (호출)
    • 클래스와 물리적 형태는 동일
    • 클래스와 다른 점은 소스를 작성할 때 선언하는 방법의 차이

     

    8.2 인터페이스 선언

     

    [public] interface 인터페이스명 { ... }

     

    • 인터페이스는 객체로 생성할 수 없기 때문에 생성자를 가질 수 없음
    • 상수와 메소드만 가질 수 있음
    interface 인터페이스명 {
        // 상수
        타입 상수명 = 값;
        // 추상 메소드
        타입 메소드명(매개변수, ...);
        // 디폴트 메소드
        default 타입 메소드명(매개변수, ...) {...}
        // 정적 메소드
        static 타입 메소드명(매개변수) {...}
    }
    • 상수: 인터페이스에 고정된 값으로, 런타임 시에 데이터를 바꿀 수 없음 - 상수 선언 시에 반드시 초기값을 대입해야 함
    • 추상 메소드: 매개값, 리턴타입만 알려줌 - 실제 실행부는 객체가 가지고 있음
    • 디폴트 메소드: 인터페이스에 선언되지만, 객체가 가지고 있는 인터페이스 메소드라고 생각해야 함
    • 정적 메소드: 객체가 없어도 인터페이스만으로 호출 가능

    1. 상수 필드 선언

    [ public static final ] 타입 상수명 = 값;

     

    2. 추상 메소드 선언

    추상 메소드: 리턴 타입, 메소드명, 매개변수만 기술, 중괄호는 붙이지 않음

    추상 메소드는 모두 public abstract의 특성을 갖기 때문에 이를 생략해도 자동적으로 컴파일 과정에서 붙게 됨

     

    3. 디폴트 메소드 선언

    디폴트 메소드는 public 특성을 갖기 때문에 public을 생략하더라도 자동적으로 컴파일 과정에서 붙음

    [public] default 리턴타입 메소드명(매개변수, ...) {...}

     

    4. 정적 메소드 선언

    형태는 클래스의 정적 메소드와 동일

    [public] static 리턴타입 메소드명(매개변수, ...) { ... }

     

     

    public interface RemoteControl {
    	// 상수
    	int MAX_VOLUME = 10;
    	int MIN_VOLUME = 0;
    	
    	// 추상 메소드
    	void turnOn();
    	void turnOff();
    	void setVolume(int volume);
    	
    	// 디폴트 메소드
    	default void setMute(boolean mute) {
    		if (mute) {
    			System.out.println("무음처리합니다.");
    		} else {
    			System.out.println("무음 해제합니다.");
    		}
    	}
    	
    	// 정적 메소드
    	static void changeBattery() {
    		System.out.println("건전지를 교환합니다.");
    	}
    }

     

    8.3 인터페이스 구현

    1. 구현 클래스

    public class 구현클래스명 implements 인터페이스명 {
        // 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
    }

        * 클래스 선언부에 implements 키워드 추가

    만약 인터페이스에 선언된 추상 메소드에 대응하는 실체 메소드를 구현 클래스가 작성하지 않으면 구현 클래스는 자동적으로 추상 클래스가 됨 -> 클래스 선언부에 abstract 키워드를 추가해야 함

     

    선언 방법: 인터페이스 변수를 선언하고 구현 객체를 대입해야 함 (객체의 번지 저장)

    인터페이스 변수 = 구현객체;

     

    2. 익명 구현 객체

    소스 파일을 만들지 않고도 구현 객체를 만들 수 있는 방법 제공 => 익명 구현 객체

     

    < 익명 구현 객체를 생성하여 인터페이스 변수에 대입하는 코드 >

    인터페이스 변수 = new 인터페이스() {
        // 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
    }

        * 중괄호 {} 에는 인터페이스에 선언된 모든 추상 메소드들의 실체 메소드를 작성

     

    익명 구현 객체를 가진 클래스를 컴파일하면 자바 컴파일러가 자동으로 클래스이름$1.class 파일을 만듦

        -> 만약 두 번째 익명 구현 객체를 만들면 $2가 생성됨

     

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

    public class 구현클래스명 implements 인터페이스A, 인터페이스 B {
        // 인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언
        // 인터페이스 B에 선언된 추상 메소드의 실체 메소드 선언
    }

     

    8.4 인터페이스 사용

    개발 코드에서 인터페이스는 클래스의 필드, 생성자 또는 메소드의 매개 변수, 생성자 또는 메소드의 로컬 변수로 선언될 수 있음

     

    1. 추상 메소드 사용

    public class RemoteControlExample {
    	public static void main(String[] args) {
    		
    		RemoteControl rc = null; // 인터페이스 변수 선언
    		
    		rc = new Television(); // Television 객체를 인터페이스 타입에 대입
    		rc.turnOn(); // 인터페이스의 turnOn(), turnOff() 호출
    		rc.turnOff(); // 인터페이스의 turnOn(), turnOff() 호출
    		
    		rc= new Audio(); // Audio 객체를 인터페이스 타입에 대입
    		rc.turnOn(); // 인터페이스의 turnOn(), turnOff() 호출
    		rc.turnOff();
    	}
    }

     

    2. 디폴트 메소드 사용

    디폴트 메소드도 구현 객체가 있어야 실행 가능

    RemoteControl rc = new Television();
    rc.setMute(true);

    setMute() 는Television에 선언되지 않았지만, setMute() 호출 가능

        ∵ 디폴트 메소드는 인터페이스의 모든 구현 객체가 가지고 있는 기본 메소드 격

            -> 구현 클래스를 작성할 때 재정의 가능

     

    3. 정적 메소드 사용

    인터페이스로 바로 호출 가능

    public class RemoteControlExample {
        public static void main(String[] args) {
            RemoteControl.changeBattery();
        }
    }

     

    8.5 타입 변환과 다형성

    인터페이스의 다형성: 프로그램 소스 코드는 변함없이 구현 객체를 교체함으로써, 프로그램의 실행 결과가 다양해지게 하는 것

     

    1. 자동 타입 변환 (Promotion)

        : 구현 객체가 인터페이스 타입으로 변환되는 것

    인터페이스 변수 = 구현객체; // 자동 타입 변환

    * 인터페이스 구현 클래스를 상속해서 자식 클래스를 만들었다면 자식 객체 역시 인터페이스 타입으로 자동 타입 변환 가능

     

    2. 매개 변수의 다형성

    매개값을 다양화하기 위해 상속에서는 매개 변수를 부모 타입으로 선언하고 호출할 때는 자식 객체를 대입함

    인터페이스 -> 매개 변수를 인터페이스 타입으로 선언하고 호출할 때는 구현 객체를 대입

     

    매개 변수의 타입이 인터페이스일 경우, 어떠한 구현 객체도 매개값으로 사용할 수 있음 (매개 변수의 다형성)

     

    3. 강제 타입 변환(Casting)

    사용이 필요한 경우: 구현 객체가 인터페이스 타입으로 자동 변환되면, 인터페이스에 선언된 메소드만 사용 가능함

    하지만, 구현 클래스에 선언된 필드와 메소드를 사용해야 할 경우도 발생

    => 강제 타입 변환으로 다시 구현 클래스 타입으로 변환하여 구현 클래스의 필드와 메소드 사용 가능

     

    4. 객체 타입 확인(instanceof)

    상속에서도 객체 타입 확인을 위해 instanceof 연산자 사용함

    < 사용 예 >

    if (vehicle instanceof Bus) {
        Bus bus = (Bus) vehicle;
    }

     

    8.6 인터페이스 상속

    인터페이스도 다른 인터페이스 상속 가능

    인터페이스는 다중 상속 허용

        - extends 키워드 뒤에 상속할 인터페이스들 나열

    public interface 하위인터페이스 extends 상위인터페이스1, 상위인터페이스2 { ... }

    하위 인터페이스로 타입이 변환되면 상.하위 인터페이스의 메소드 사용 가능

     

    8.7 디폴트 메소드와 인터페이스 확장

    인터페이스에서 디폴트 메소드를 허용한 이유: 기존 인터페이스를 확장해서 오류 없이 새로운 기능을 추가하기 위함

     

    1. 디폴트 메소드가 있는 인터페이스 상속

    부모 인터페이스에 디폴트 메소드가 정의되어 있을 경우, 자식 인터페이스에서 디폴트 메소드를 활용하는 방법

    • 디폴트 메소드를 단순 상속 받기
    • 디폴트 메소드를 재정의(Override)해서 실행 내용 변경
    • 디폴트 메소드를 추상 메소드로 재선언
Designed by Tistory.