인터페이스
인프런 Do it! 자바 프로그래밍 입문 수강 중
인터페이스란?
모든 메서드가 추상 메서드로 이루어진 클래스를 의미하며 형식저인 선언만 있고 구현은 없다.
- 인터페이스에 모든 메서드는 추상 메서드로
public abstract
로 선언한다- 인터페이스에 모든 변수는 상수로
public static final
로 선언한다
예시
interface 인터페이스 이름{
public static final float pi = 3.14f;
public void add();
}
인터페이스의 모든 추상 메서드를 구현하지 않으면 추상 클래스가 된다.
추상클래스 VS 인터페이스
- 인터페이스는
interface
키워드를 사용해 선언하고extends
키워드를 사용해 다중 상속을 구현한다. - “is able to”로 표현하며 “클래스가 무엇을 할 수 있다”라고 하는 공통된 기능을 구현하도록 강제하는 것
인터페이스 구현과 형 변환
- 인터페이스로 구현한 클래스는 인터페이스 형으로 선언한 변수로 형 변환 할 수 있다.
- 상속에서의 형 변환과 동일한 의미를 가진다.
- 형 변환시 사용할 수 있는 메서드는 인터페이스에 선언된 메서드만 사용할 수 있다.
- 클래스 상속과 달리 구현 코드가 없기 때문에 여러 인터페이스를 구현할 수 있다.
public class CompleteCalc implements Calc, Runnable{ // 여러 implements 구현 가능
...
}
인터페이스와 다형성
- 인터페이스는 클라이언트 코드와 서비스를 제공하는 객체 사이의 약속
- 어떤 객체가
interface
타입이라는 것은 그 인터페이스가 제공하는 메서드를 구현했다는 의미 - 클라이언트는 어떻게 구현되었는지 상관 없이 인터페이스의 정의만을 보고 사용할 수 있음
ex) JDBC - 다양한 구현이 필요한 인터페이스를 설계하는 것은 매우 중요한 일
인터페이스 요소
- 상수: 모든 변수는 상수로 변환 됨
- 추상 메서드: 모든 메서드는 추상 메서드로 구현 됨
- default 메서드: 기본 구현을 가지는 메서드로 구현 클래스에서 재정의 할 수 있음
- static 메서드: 인스턴스 생성과 상관 없이 인터페이스 타입으로 사용할 수 있는 메서드
- private 메서드: 인터페이스를 구현한 클래스에서 사용하거나 재정의 할 수 없음. 인터페이스 내부에서만 기능을 제공하기 위해 구현하는 메서드
default 메서드 재정의
public interface Calc{
...
default void description(){
System.out.println("정수 계산기 구현"); //Java8 부터 제공
}
}
public class CompleteCalc extends Calculator{
...
@override
public void dexcription(){
System.out.println("완전한 계산기 구현"); // default 메서드 언하는 기능으로 재정의
}
}
static 메서드
public interface Calc{
...
static int total(int[] arr){
int total = 0;
for(int i : arr){
total += i;
}
}
return total;
}
int[] arr = {1, 2, 3, 4, 5};
int sum = Calc.total(arr); // 인스턴스 생성 없이 사용 가능
private 메서드
인터페이스 내부에서 private
혹은 private static
으로 선언한 메서드를 구현한다.
public interface Calc{
...
default void description(){
System.out.println("정수 계산기 구현");
myMethod(); // default 메서드에서 private 메서드 호출
}
static int total(int[] arr){
int total = 0;
for(int i : arr){
total += i;
}
myStaticMethod(); // static 메서드에서 private static 메서드 호출
}
return total;
}
private void myMethod(){
System.out.println("private 메서드 호출");
}
private static void myStaticMethod(){
System.out.println("private static 메서드 호출");
}
두 개의 인터페이스 구현
Buy 인터페이스
public interface Buy{
void buy();
}
Sell 인터페이스
public interface Sell{
void sell();
}
Customer 인터페이스
public class Customer implements Buy, Sell{
@Override
public void buy(){
System.out.println("구매하기");
}
@Override
public void sell(){
System.out.println("판매하기");
}
}
테스트
Customer customer = new Customer(); //구매, 판매 모두 가능
customer.buy();
customer.sell();
Buy buyer = customer;
buyer.buy(); // 구매만 가능
Sell seller = customer;
seller.sell(); // 판매만 가능
두 개의 인터페이스로부터 implements 했을 경우 같은 이름의 default 메서드가 있을 수 있다. 그럴 때는 구현 시 오버라이딩 해주어야 한다.
Buy 인터페이스
public interface Buy{
void buy();
default void order(){
System.out.println("구매 주문");
}
}
Sell 인터페이스
public interface Sell{
void sell();
default void order(){
System.out.println("판매 주문");
}
}
Customer 인터페이스
public class Customer implements Buy, Sell{
@Override
public void buy(){
System.out.println("구매하기");
}
@Override
public void sell(){
System.out.println("판매하기");
}
@Override
public void order(){ // 메서드의 이름이 동일하기 때문에 오버라이딩이 필요함
System.out.println("고객 판매 주문");
}
}
테스트
Customer customer = new Customer();
Buy buyer = customer;
Sell seller = customer;
customer.order(); //고객 판매 주문 출력
buyer.order(); //고객 판매 주문 출력
seller.order(); //고객 판매 주문 출력
Java는 모드 가상 메서드 방식이기 때문에 오버라이딩 된 인스턴스의 메서드가 출력이 된다.
인터페이스 상속
인터페이스 간에도 상속이 가능한 데 구현 코드의 상속이 아니기 때문에 형 상속(type inheritance) 라고 한다.
인터페이스 구현과 클래스 상속을 함께 사용하는 것도 가능하다.
예시
public class BookShelf extends Shelf implements Queue{
...
}
끝!