인터페이스
구현 코드가 아예 없으며 클래스 대신 interface라고 붙이면 된다.
public interface Calc {
double PI = 3.14;
int ERROR = -99999999;
public int add(int a, int b);
public int sub(int a, int b);
public int mul(int a, int b);
public int div(int a, int b);
}
인터페이스의 역할
구현코드도 없는데 대체 왜 사용할까?
설계 단계에서 명세서 역할을 한다. 클라이언트 프로그램에 어떤 메서드를 제공하는지 알려주는 것이다.
사용자는 인풋, 아웃풋만 알면 될뿐...구현 과정은 알 필요가 없기 때문이다.
따라서 '한 객체가 어떤 인터페이스의 타입이다' = 그 객체가 인터페이스의 메서드를 구현했다 는 의미이다.
인터페이스를 통한 다형성 구현
인터페이스를 통해 다양한 객체를 구현한다.
예를 들어 자바의 JDBC (자바 프로그램과 DBMS를 연결해주는 라이브러리. sql 쿼리문 실행법 등이 구현되어 있다.)는 오라클, MYSQL, MSSQL등 각 DB 사에서 구현한다.
그러면 유저는 각 메서드가 어떤 역할을 하는지만 알고 가져다 쓴다.
인터페이스 구성 요소
- 상수: 선언된 모든 변수는 상수임
- 메서드: 모든 메서드는 추상 메서드(구현부 없음)
- default 메서드: 구현을 갖는 메서드. 구현하는 클래스에서 재정의가능. 주로 중복된 이름의 메서드에 적용한다.
- static 메서드: 인스턴스 생성과 상관없이 인터페이스 타입으로 호출하는 메서드
- private 메서드: 인터페이스 내에서 사용하기 위해 구현한 메서드. 구현하는 클래스에서 재정의 불가능
이 중에서 default, static 메서드는 java 8부터, private 메서드는 java 9부터 적용되는 메서드이다.
private 메서드는 두 가지가 존재하는데 같은 static 메서드에서 사용가능한 private static과 일반 메서드에서 사용가능한 private 메서드가 존재한다.
public interface Buy {
void buy();
default void order() {
System.out.println("구매하세요");
};
// 중복 메서드에 대해 적용된다. 같은 이름의 메서드가 존재할 때에 구분하기 위해 미리 구현부가 존재한다.
static int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
}
public interface Sell {
void sell();
default void order() {
System.out.println("판매하세요");
};
}
이름이 중복된 order의 경우 Buy나 Sell 중 하나를 선택할 수 있다.
public class Customer implements Buy, Sell {
@Override
public void sell() {
System.out.println("물건을 판매");
}
@Override
public void buy() {
System.out.println("물건을 구매");
}
@Override
public void order() {
Sell.super.order();
//Buy.super.order();도 가능
}
}
public class CustomerTest {
public static void main(String[] args) {
Customer customer = new Customer();
customer.buy();
customer.sell();
customer.order();
int[] arr = { 12, 3, 4, 5 };
System.out.println(Buy.getSum(arr)); //static 메서드 사용 가능
Buy buyer = new Customer();
buyer.buy(); // only buy available
buyer.order();
}
}
buyer의 경우 Customer이지만 Buy가 Sell을 상속하지 않기 때문에 sell 메서드는 사용 불가능하다.
대신 buyer.order은 인스턴스에서 구현된 메서드가 호출된다.
타입상속과 형변환
인터페이스를 구현한 클래스는 인터페이스 타입으로 변수를 선언하여 인스턴스를 생성할 수 있다.
인터페이스 상속은 타입 상속이라고도 불린다.
Calc calc = new CompleteCalc();
public abstract class Calculator implements Calc {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int sub(int a, int b) {
return a - b;
}
}
Calculator는 Calc 인터페이스를 상속한다. abstract로 선언하여 전체를 다 구현하지 않고 일부만 구현했다.
public class CompleteCalculator extends Calculator {
@Override
public int mul(int a, int b) {
return a * b;
}
@Override
public int div(int a, int b) {
if (b == 0) {
return ERROR;
}
return a / b;
}
public void showInfo() {
System.out.println("계산기입니다.");
}
}
CompleteCalculator는 Calculator를 extends한다.
상위 클래스인 Calculator에서 구현하지 않은 나머지 메서드를 구현해야 한다.(안하면 에러남)
public class CalcTest {
public static void main(String[] args) {
CompleteCalculator cc = new CompleteCalculator();
System.out.println(cc.add(1, 2));
System.out.println(cc.sub(1, 2));
System.out.println(cc.mul(1, 2));
System.out.println(cc.div(1, 2));
cc.showInfo();
Calculator cal = new CompleteCalculator();
System.out.println(cal.add(1, 2));
System.out.println(cal.sub(1, 2));
System.out.println(cal.mul(2, 0)); // 이미 정의된 인스턴스의 함수가 실행된다.
System.out.println(cal.div(1, 0));
// cal.showInfo(); 상위 클래스에 정의되지 않은 메서드는 사용 불가능
Calc c = new CompleteCalculator();
}
}
CompleteCalculator로 선언된 cal은 상위클래스인 Cal에 선언된 mul, div는 사용가능하다.
그러나 CompleteCalculator에만 선언된 showInfo()는 사용 불가능하다.
'프로그래밍 언어 > java' 카테고리의 다른 글
[java] Object 클래스 (0) | 2021.03.18 |
---|---|
[java] 인터페이스 다중 상속 (0) | 2021.03.12 |
[java] final, 템플릿 메서드 (0) | 2021.03.11 |
[java] 추상클래스 (0) | 2021.03.11 |
[java] 업캐스팅, 타운캐스팅 (0) | 2021.03.10 |
댓글