인터페이스의 역할
인터페이스는 객체의 사용방법을 정의한 타입
객체의 교환성을 높여주기 때문에 다형성을 구현하는 매우 중요한 역할
자바8의 람다식은 함수적 인터페이스의 구현 객체를 생성
인터페이스는 개발 코드와 객체가 서로 통신하는 접점 역할
개발 코드가 인터페이스의 메소드를 호출 -> 인터페이스는 객체 메소드 호출
개발 코드는 객체의 내부 구조를 알 필요가 없다.
인터페이스의 메소드만 알고 있으면 된다.
개발 코드가 직접 객체의 메소드를 호출 하면 간단
-> 개발코드를 수정하지 않고 사용하는 객체를 변경할수 있도록 하기 위함
인터페이스는 하나의 객체가 아니라
여러 객체들과 사용이 가능 하므로 어떤 객체를 사용하느냐에 따라
실행 내용과 리턴값이 다를 수 있다.
개발 코드 측면에서는 코드 변경 없이 실행 내용과 리턴값을 다양화 할 수있다는 장점
인터페이스 선언
인터페이스는 ~.java 로 소스파일로 작성
컴파일러(javac.exe)를 통해 ~.class 형태로 컴파일
물리적 형태는 클래스와 동일
차이점을 소스를 작성할때 선언하는 방법이 다름
인터페이스 선언
인터페이스 선언은 class 키워드 대신에 interface 키워드 사용
[public] interface 인터페이스명{...}
인터페이스 이름은 클래스 이름을 작성하는 방법과 동일
영어 대소문자 구분
첫문자 대문자 하고 나머지를 소문자로 작성하는 것 관례
public 접근 제한은 다른 패키지에서도 인터페이스를 사용할수 있게 함
클래스 -> 필드 생성자 메소드
인터페이스 -> 상수, 메소드
자바 7 - 실행 블록이 없는 추상메소드만 가능
자바 8 - 디폴트 메소드와 정적 메소드 선언 가능
interface 인터페이스명{
//상수
타입 상수명 = 값;
// 추상 메소드
타입 메소드명(매개변수, ...);
// 디폴트 메소드
default 타입 메소드명(매개변수, ...){...}
// 정적 메소드
static 타입 메소드명(매개변수){...}
}
상수 필드(Constant Field)
인터페이스는 객체 사용 설명서
런타임 시 데이터를 저장할 수 있는 필드를 선언 할수 없다
상수는 고정값 -> 런타임시 변경 불가
상수를 선언할 때는 반드시 초기값 대입
추상 메소드(Abstract Method)
추상 메소드는 객체가 가지고 있는 메소드를 설명 한 것
호출할때 어떤 매개값 필요, 리턴 타입만 알려줌
실행는 객체(구현 객체) 가지고 있다.
디폴트 메소드(Default Method)
인터페이스에 선언 되지만 사실을 객체(구현 객체)가 가지고 있는 인스턴스 메소드
자바 8에서 디폴트 메소드를 허용한 이유 => 기존 인터페이스 확장하여 새로운 기능을 추가
정적 메소드(Staic Method)
자바 8 부터 작성 허용, 객체가 없어도 인터페이스 만으로 호출 가능
상수 필드 선언
인터페이스는 데이저 저장 불가
상수 필드 선언 가능, 모두 public static final의 특성을 가짐, 생략 해도 자동적으로 컴파일 과정에서 붙게 된다
상수 -> public static final 타입 상수명 = 값;
[public static final] 타입 상수명 = 값;
상수명은 대문자 작성, 서로 다른 단어로 구성되어 있을 경우
언더바(_)로 연결하는 것이 관례
MODEL, MAX_VALUE와 같이 선언
인터페이스 상수는 static{} 블록으로 초기화 할 수 없다
때문에 반드시 선언과 동시에 초기값을 지정
추상 메소드 선언
인터페이스를 통해 호출된 메소드는 최종적으로 객체에서 실행
인터페이스의 메소드는 실행 블록이 필요 없는 추상 메소드로 선언
추상 메소드 리턴 타입, 메소드명, 매개 변수만 기술
중괄호{}를 붙이지 않는 메소드를 말함
인터페이스에 선언된 추상 메소드는 모두 public abstract 특성을 갖기 때문
public abstract를 생략 하더라도 자동적으로 컴파일 과정에서 붙게 됨
디폴트 메소드 선언
자바 8에서 추가된 인터페이스의 새로운 멤버
클래스 인스턴스의 메소드와 동일
default 키워드 리턴 타입 앞에 붙음
디폴트 메소드는 public 특성 갖기 때문 public을 생략하더라도 자동적으로 컴파일 과정에서 붙게 됨
[public] default 리턴타입 메소드명(매개변수, ...){...}
정적 메소드 선언
자바 8에서 추가된 인터페이스 새로운 멤버
클래스의 정적 메소드와 완전 동일
public 특성을 갖기 대문 public 을 생략하더라도 자동적으로 컴파일 과정에서 붙게 됨
[public] static 리턴타입 메소드명(매개변수, ...){....}
인터페이스 구현
개발 코드 -> 인터페이스 메소드 호출 -> 객체의 메소드 호출
객체 -> 인터페이스 내 정의된 추상메소드 와 동일한 메소드 이름, 매개 타입 ,리턴 타입을 가진 실체메소드 소유 필요
-> 이리헌 객체 : 인터페이스 구현 객체
=> 구현 객체를 생성하는 클래스 : 구현 클래스
구현 클래스
구현 클래스는 보통의 클래스와 동일
인터페이스 타입으로 사용 할 수 있음 -> 클래스 선언부에 implenments 키워드 추가 인터페이스 명 명시
public class 구현클래스명 implements 인터페이스명{
//인터페이스에 선언된 추상 메소드의 실체 메소드 선언
}
인터페이스의 모든 메소드는 기본 public 접근 제한을 갖기 때문
-> public 보다 더 낮은 접근 제한으로 작성 할수 없다.
* pulbic 생략시 : Cannot reduce the visibility of the inherited method 컴파일 에러
인터페이스 선언된 추상 메소드에 대응하는
실체 메소드를 구현 클래스가 작성하지 않으면
구현 클래스는 자동적으로 추상 클래스가 된다
그렇기 때문에 클래스 선언부에 abstract 키워드를 추가 해야함
public abstract class 클래스이름 implement 인터페이스이름 {
public 리턴타입 추상 메소드이름(){..} - > 일부만 구현
}
구현 클래스가 작성되면 new 연사자로 객체를 생성 가능
인터페이스 변수를 선언 하고 구현객체를 대입
인터페이스 변수 = 구현객체; | 인터페이스 변수;
변수 = 구현객체;
익명 구현 객체
구현 클래스를 만들어 사용하는 것이 일반적, 클래스 재사용 할수 있기 편리
But 일회성의 구현 객체를 만들기 위해 소스파일을 만들고 클래스를 선언하는것은 비효율적
자바 소스 파일을 만들지 않고도 구현 객체를 만들 수 있는 방법을 제공
-> 익명 구현 객체
- 자바 UI 프로그래밍에서 이벤트 처리, 임시 작업 스레드를 만들기 위함
자바 8에서 지원하는 람다식은 인터페이스의 익명 구현 객체 만듬
*하나의 실행문으로 끝에는 세미콜로을 반드시 붙여야함
인터페이스 변수 = new 인터페이스(){
//인터페이스에 선언된 추상 메소드의 실체 메소드 선언
};
new -> 뒤에 이름이 없음,
인터페이스(){} 인터페이스를 구현해서 중괄호 {} 와 갈티 클래스를 선언
new 연산자는 이렇게 선언된 클래스를 객체로 생성
중괄호 {}에는 인터페이스 선언된 모든 추상 메소드들의 실체 메소드를 작성
-> 안할시 컴파일 에러
추가적으로 필드와 메소드 선언 시
익명 객체 안에서만 사용, 인터페이스 변수로 접근 불가
모든 객체는 클래스로부터 생성
-> 익명 구현 객체도 예외는 아님
자바 컴파일러에 의해 자동으로 이름$1.class 클래스 파일 이 만들어짐
생성 번호는 1부터 시작
다중 인터페이스 구현 클래스
객체는 다수의 인터페이스 타입 으로 사용 가능
인터페이스 A, 인터페이스 B 객체 메소드 호출하려면 모든 인터페이스를 구현 해야 함.
public class 구현클래스명 implements 인터페이스A, 인터페이스B {
// 인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언
// 인터페이스 B에 선언된 추상 메소드의 실체 메소드 선언
}
실체 메소드, 모두 작성하지 않을시 -> 추상클래스로 선언해야함
인터페이스 사용
인터페이스 변수를 선언, 구현객체를 대입
인터페이스 변수는 참조 타입 -> 구현객체 대입 -> 구현 객체 번지를 저장
인터페이스 변수; | 인터페이스 변수 = 구현객체;
변수 = 구현객체 ; |
개발 코드에서 인터페이스는 클래스의 필드, 생성자, 메소드의 매개변수, 생성자, 메소드의 로컬변수 선언 가능
추상 메소드 사용
구현 객체가 인터페이스 타입에 대입되면 인터페이스에 선언된 추상 메소드를 개발 코드에서 호출
디폴트 메소드 사용
디폴트 메소드는 인터페이스에 선언되었지만, 인터페이스에서 사용 불가
디폴트 메소드는 모든 구현 객체가 가지고 있는 기본 메소드
구현 클래스를 작성하때 디폴트 메소드를 재정의(오버라이딩)해서 자신에게 맞게 수정
정적 메소드 사용
인터페이스의 정적 메소드는 인터페이스 바로 호출 가능
타입 변환과 다형성
인터페이스도 다형성을 구현하는 기술이 사용
상속보다 인터페이스를 통해 다형성을 구현하는 경우가 더 많다
다형성 : 하나의 타입에 대입되는 객체에 따라서 실행 결과가 다양항 형태로 나오는 성질
상속 : 같은 종류의 하위 클래스르 만드는 기술
인터페이스 : 사용 방법이 동일 클래스를 만드는 기술
인터페이스를 사용해서 메소드를 호출하도록 코딩 했다면
구현 객체를 교체하는 것은 매우 손쉽고 빠르게 할수 있다.
-> A클래스를 이용해서 프로그램을 개발
개발 완료후, 테스트, B클래스로 바꾸기로 결심
B클래스의 메소드는 A클래스의 메소드와 이름, 매개변수가 다름
A클래스의 메소드가 사용된 곳을 찾아 B클래스의 메소드로 변경
A 클래스와 B클래스의 메소드 선언부가 동일하면?
메소드 호출 방법이동일 하므로 메소드 호출 코드는 수정 필요 X
객체 생성 부분만 A클래스에서 B클래스로 교체
A, B 설계 할때 메소드 선언부를 완전히 동일하게 설계할수 있는가?
-> 인터페이스 작성
인터페이스 메소드는 매개변수로 많이 등장,
인터페이스 타입으로 매개 변수 선언
메소드 호출 시 매개값으로 여러가지 종류 구현 객체를 줄수 있기 때문
메소드 실행 결과가 다양
-> 인터페이스 매개변수의 다형성
자동 타입 변환(Promotion)
구현 객체가 인터페이스 타입으로 변환 되는 것은 자동 타입 변환(Promotion)에 해당
프로그램 실행 도중에 자동적으로 타입 변환이 일어나는것
* 인터페이스 구현 클래스를 상속해서 자식 클래스를 만들었다면 자식 객체 역시 인터페이스 타입으로 자동 타입 변환
필드의 다형성과 매개변수 다형성 구현
필드의 다형성
필드 값으로 객체를 대입
메소드의 수정 없이 다야항 메소드 실행 결과를 얻을수 있음
인터페이스 배열로 구현 객체 관리
인터페이스[] 참조변수 = {구현 클래스 , 구현 클래스 }
for(인터페이스 변수 : 참조변수){
변수.메소드();
}
매개 변수의 다형성
자동 타입 변환 필드의 값을 대입 할때 발생
메소드 호출 할때 많이 발생
매개변수 부모타입, 인터페이스 타입 선언 -> 자식클래스, 구현 객체 선언
인터페이스 참조함수 = 구현클래스;
자동 타입 변환
강제 타입 변환(Casting)
구현 객체가 인터페이스 타입으로 자동 변환 하면 인터페이스에 선언 된 메소드만 사용 가능
-> 구현 클래스 선언된 필드 메소드를 사용해야 할 경우 발생
-> 강제 타입 변환 다시 구현 클래스로 타입 변환
(강제 타입 변환)
구현클래스 변수 = (구현클래스) 인터페이스변수;
객체 타입 확인(instanceof)
강제 타입 변환은 구현 객체가 인터페이스 타입으로 변환 되어 있는 상태에서 가능
어떤 구현객체가 지정될지 모르는 상황에서 강제 타입 변환시 ClassCastException 발생
-> instanceof 연산자 사용
인터페이스 상속
인터피에스도 다른 인터페이스 상속
인터페이스는 클래스와 달리 다중 상속 허용
public interface 하위인터페이스 extends 상위인터페이스1, 상위인터페이스2 {...}
하위 인터페이스를 구현 -> 하위 인터페이스 메소드 뿐 아니라 -> 상위 인터페이스 모든 추상 메소드
실체 메소드 구현 필요
구현 클래스로부터 -> 상위 하위 인터페이스 타입으로 변환 가능
하위인터페이스 변수 = new 구현클래스(...);
상위인터페이스1 변수 = new 구현클래스(...);
상위인터페이스2 변수 = new 구현클래스(...);
하위 인터페이스로 타입 변환이 되면 상.하위 인터페이스 선언된 모든 메소드 사용 가능
상위 인터페이스 변환시 상위 인터페이스 선언된 메소드만 사용 가능
디폴트 메소드와 인터페이스 확장
인터페이스에 선언된 인스턴스 메소드이기 때문에 구현 객체가 있어야 사용 가능
선언은 인터페이스에서 하고, 사용은 구현 객체를 통해 하는 것 어색
디폴트 메소드의 필요성
기존 인터페이스 확장해서 새로운 기능을 추가하기 위함
기존 인터페이스의 이름과 추상메소드의 변경 없이 디폴트 메소드만 추가
이전에 개발한 구현 클래스를 그대로 사용할 수 있으면서
새롭게 개발하는 클래스는 디폴트 메소드를 활용
디폴트 메소드가 있는 인터페이스 상속
부모 인터페이스에 디폴트 메소드가 정의 되어 있을 경우,
자식 인터페이스에서 디폴트 메소드를 활용하는 방법
- 디폴트 메소드를 단순히 상속만 받음
- 디폴트 메소드를 재정의(Override)해서 실행 내용을 변경
- 디폴트 메소드를 추상 메소드로 재선언
추상메소드로 재선언시 -> 구현 클래스가 디폴트 메소드 구현 해야함
@Override
public void 디폴트 메소드명();
'Back-end > 이것이 자바다[신용권 한빛미디어]' 카테고리의 다른 글
예외 처리 (0) | 2021.10.22 |
---|---|
중첩 클래스와 중첩 인터페이스 (0) | 2021.10.10 |
추상 클래스 (0) | 2021.10.04 |
타입 변환과 다형성 (0) | 2021.10.04 |
상속 (0) | 2021.10.04 |