희렌버핏

8장 인터페이스 본문

카테고리 없음

8장 인터페이스

Oliviakim 2019. 2. 18. 20:21

8.1 인터페이스의 역할

- 개발코드는 객체의 내부구조 알 필요 없고 인터페이스의 메소드만 알고 있으면 된다.

- 인터페이스 : 개발코드와 객체가 서로 통신하는 접점

- 개발 코드 변경 없이 리턴값 또는 실행 내용이 다양해질 수 있다. (다형성)

- 개발 코드가 객체에 종속되지 않게 해서 객체를 교체할 수 있도록 하는 역을 한다.


8.2 인터페이스 선언

8.2.1 인터페이스 선언

- 인터페이스 이름 : 규칙에 따라 작성

- 첫자는 대문자

- 숫자로 시작하면 안되고, '$'와 '_'만 됨

- 다른 단어 결합하면 대문자로 변경

- 소스 파일 생성

- 인터페이스 이름과 대소문자가 동일한 소스 파일 생성 (인터페이스명.java)

- 인터페이스 선언

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

- 인터페이스 구성 멤버

- 상수 / 추상 메소드 / 디폴트 메소드 / 정적 메소드

interface 인터페이스명 {

타입 상수명 = 값; //상수

타입 메소드명(매개변수,...); //추상 메소드

default 타입 메소드명(매개변수,...) {...} //디폴트 메소드

static 타입 메소드명(매개변수) {...} //정적 메소드

}

8.2.2 상수 필드 선언

- 인터페이스는 상수 필드만 선언 가능 (데이터 저장 안해서 데이터 저장할 인스턴스나 정적 필드 필요 없다.)

- 인터페이스에 선언된 필드는 모두 public static final의 특징을 가짐. (필드 선언 시 생략해도 컴파일 과정에서 자동으로 붙는다.)

- 상수명은 대문자로 시작 (서로 다른 단어 구성 연결은 '_'로)

- 선언과 동시에 초기값 지정 (블록 작성할 수 없어, static {}으로 초기화 할 수 없다)

8.2.3 추상 메소드 선언

- 인터페이스를 통해 호출된 메소드는 최종적으로 객체에서 실행

- 인터페이스 메소드는 실행블록 없는 추상메소드로 선언 (추상 메소드 선언 없이 메소드 선언만 해도 컴파일러 과정에서 자동으로 abstract가 붙는다.)

8.2.4 디폴트 메소드 선언

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

실행 스크립트

}

- 실행 블럭을 가지고 있는 메소드

- default 키워드를 반드시 붙여야 한다.

- 기본적으로 public 접근 제한을 가진다. 생략해도 컴파일 과정에서 자동으로 붙는다.

8.2.5 정적 메소드 선언

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

}


8.3 인터페이스 구현

- 구현 객체 : 인터페이스의 추상메소드에 대한 실체를 가진 객체

- 구현 클래스 : 구현 객체를 생성하는 클래스

- 구현 클래스 선언

- 자신의 객체가 인터페이스 타입으로 사용할 수 있음 명시

public class 구현클래스명 implements 인터페이스명 {

//인터페이스에 선언된 추상 메소드의 실체 메소드 선언

}

- 실체 메소드를 작성하는 방법

- 메소드 선언부가 명확히 일치 돼야함

- 인터페이스에 있는 모든 추상 메소드가 실체 메소드로 재정의 되어야 한다. (모든 메소드가 재정의 되지 않으면 추상클래스로 작성)

- 실체 메소드들은 반드시 public을 붙여준다. (인터페이스의 기본 접근제한자가 public이기 때문에 public보다 낮은 접근 제한으로 작성할 수 없다)

- @Override를 이용해서 컴파일러로 정확히 작성 됐는지를 점검.

- 인터페이스 변수와 구현 객체

- 인터페이스 변수 = 구현객체; (구현객체에는 인터페이스에서 implements한 클래스만 올 수 있다.)


8.3.2 익명 구현 객체

- 이름 없는 클래스를 만들어서 바로 객체를 생성한 후 인터페이스 변수에 대입할 수 있다.

- 명시적인 구현 클래스 작성을 생략하고 바로 구현 객체를 얻는 방법

- 이름이 없는 구현 클래스 선언과 동시에 객체를 생성

인터페이스 변수 = new 인터페이스( ) {   //생성자 호출처럼 보이지만 중괄호 안처럼 클래스를 생성하겠다는 것.

// 중괄호 안에 선언된 기본 생성자를 호출해서 객체를 만들어 인터페이스 변수에 대입하겠다.

//인터페이스에 선언된 추상 메소드의 실체 메소드 선언

};

* 인터페이스는 직접 객체를 생성할 수 없어 생성자가 없다. (인터페이스는 객체의 사용방법을 기술한 것이지 객체 자체를 만들기 위한 설계도는 아니다.)

- 인터페이스의 추상 메소드들을 모두 재정의하는 실체 메소드가 있어야 한다.

- 추가적으로 작성한 필드와 메소드는 익명 객체 안에서만 사용할 수 있다. 인터페이스 변수로 접근 불가. (인터페이스에 작성되어 있는게 아니기 때문에)

- 주로 사용되는 곳

- UI 프로그래밍(Swing, java Fx, Android)에서 이벤트를 처리하기 위해 주로 사용

- 임시 작업 스레드를 만들기 위해 사용

- 자바8부터 지원하는 람다식은 내부적으로 익명 구현 객체를 사용

- 익명 구현 객체도 클래스(바이트코드) 파일을 가지고 있다. (익명 구현객체를 작성하고 클래스 작성 없었는데도 파일을 내부적으로 생성함)

- 클래스 $번호.class 파일명으로 생성된다. (익명 구현 객체의 수에 맞게 번호가 올라간다.)


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

public class 구현클래스명 implements 인터페이스 A, 인터페이스 B {

//인터페이스 A와 B가 가지고 있는 모든 추상 메소드 재정의

}


8.4 인터페이스 사용

- 인터페이스에 구현 객체를 대입하는 방법

1. 필드 : RemoteControl rc = new Television( );  //구현 객체가 초기값으로 대입

2. 생성자 : 매개변수로 인터페이스 변수를 선언, 객체 생성할 때 객체 대입 가능, 인터페이스의 구현객체라면 얼마든지

MyClass(RemoteControl rc){

this.rc = rc;

}

3. 메소드 : 로컬 변수로 인터페이스 변수를 선언해서

void methodA() {

//로컬 변수

RemoteControl rc = new Audio();

}

void methodB(RemoteControl ro) {...}  <=  mc.methodB(new Audio());


8.4.1 추상 메소드 사용

RemoteControl rc = new Television( );

rc.turnOn();    =>    Television의 turnOn() 실행

rc.turnOff();    =>    Television의 turnOff() 실행


8.4.2 디폴트 메소드 사용

- 추상메소드와 차이점은 실행 블록은 직접 가지고 있다는 것

- 구현객체를 인터페이스 변수에 대입해야만 호출할 수 있다.

- 모든 구현 객체가 가지고 있는 기본 메소드로 사용한다. (필요에 따라 디폴트 메소드를 재정의해서 사용할 수 있다.)


8.4.3 정적 메소드 사용