class or 프로그램이 제공하는 기능을 명시적으로 선언하는 역할
추상메서드와 상수로만 이루어져있어 인스턴스를 생성할 수 없다
인터페이스를 이용하여 계산기 만들기
public interface Calc {
double PI = 3.14; // 인터페이스에서 선언한 변수는 컴파일 과정에서 상수로 변함
int Error = -999999;
int add(int num1, int num2); // 인터페이스에서 선언한 메서드는 추상 메서드로 변함
int substract(int num1, int num2);
int divide(int num1, int num2);
int multiply(int num1, int num2);
int square(int num1);
// 디폴트 메서드 : 인터페이스에서 구현 코드까지 작성한 메서드
default void description() {
System.out.println("정수 계산기 구현");
myMethod();
}
// 정적 메서드 : 인스턴스 생성과 상관없이 사용할 수 있는 메서드
static int total(int[] arr) {
int total = 0;
for(int i : arr) {
total += i;
}
myStaticMethod();
return total;
}
private void myMethod() {
System.out.println("private 메서드");
}
private static void myStaticMethod() {
System.out.println("private static 메서드");
}
}
public abstract class Calculator implements Calc{
@Override
public int add(int num1, int num2) {
// TODO Auto-generated method stub
return num1 + num2;
}
@Override
public int substract(int num1, int num2) {
// TODO Auto-generated method stub
return num1 - num2;
}
@Override
public void description() {
// TODO Auto-generated method stub
System.out.println("Calculator 추상 클래스");
}
}
public class CompleteCalc extends Calculator {
@Override
public int divide(int num1, int num2) {
// TODO Auto-generated method stub
if(num2 != 0) {
return num1/num2;
}
else {
return Calc.Error;
}
}
@Override
public int multiply(int num1, int num2) {
// TODO Auto-generated method stub
return num1 * num2 ;
}
public void showInfo() {
System.out.println("Calc 인터페이스 구현");
}
@Override
public int square(int num1) {
// TODO Auto-generated method stub
return num1 * num1;
}
}
public class CalcMain {
public static void main(String[] args) {
CompleteCalc calc = new CompleteCalc();
int num1 = 10, num2 = 20;
System.out.println(calc.add(num1, num2));
System.out.println(calc.substract(num1, num2));
System.out.println(calc.divide(num1, num2));
System.out.println(calc.multiply(num1, num2));
System.out.println(calc.square(num1));
calc.showInfo();
//디폴트 메서드
calc.description();
//정적메서드 사용하기
int[] arr = {1, 2, 3, 4, 5};
System.out.println(Calc.total(arr));
}
}
알아야할점
1. Calc 와 Calculator로는 인스턴스를 생성할 수 없다.
2. 인터페이스를 구현할때에는 implements 를 사용
3. 인터페이스의 변수는 - 상수로 바뀜
4. 인터페이스에서 선언한 메서드는 추상메서드로 변환
인터페이스를 사용하면 다형성을 구현해 확장성 있는 프로그램 만들수 있다.
즉 클라이언트 프로그램을 많이 수정하지 않고 기능 추가, 다른기능 사용을 할 수 있다.
ex> 고객센터 상담원에게 배분하는 정책 프로그램
위의 그림처럼 3가지 시나리오를 만들었는데 Scheduler 인터페이스를
만들고 공통으로 사용하는 메서드 getNextCall() SendCallToAgent()를 만든다.
public interface Scheduler {
public void getNextCall();
public void sendCallToAgent();
}
public class RoundRobin implements Scheduler{
@Override
public void getNextCall() {
// TODO Auto-generated method stub
System.out.println("상담전화를 순서대로 대기열에서 가져옴");
}
@Override
public void sendCallToAgent() {
// TODO Auto-generated method stub
System.out.println("다음순서 상담원에게 배분 ");
}
}
public class LeastJob implements Scheduler {
@Override
public void getNextCall() {
// TODO Auto-generated method stub
System.out.println("상담전화 순서대로 대기열에서 가져옴");
}
@Override
public void sendCallToAgent() {
// TODO Auto-generated method stub
System.out.println("현재 상담 업무 없거나 대기가 가장 적은 상담원에게 할당");
}
}
public class PriorityAllocation implements Scheduler {
@Override
public void getNextCall() {
// TODO Auto-generated method stub
System.out.println("고객 등급이 높은 전화 먼저가져옴");
}
@Override
public void sendCallToAgent() {
// TODO Auto-generated method stub
System.out.println("업무 skill이 높은 상담원에게 우선적으로 배분 ");
}
}
import java.io.IOException;
public class clientMain {
public static void main(String[] args) throws IOException {
System.out.println("전화 상담 할당 방식 선택");
System.out.println("R : 한명씩 차례로 할당");
System.out.println("L : 쉬고 있거나 대기가 가장 적은 상담원에게 할당");
System.out.println("P: 우선순위가 높은 고객 먼저 할당");
int ch = System.in.read();
Scheduler scheduler = null;
if(ch =='R' || ch == 'r') {
scheduler = new RoundRobin();
}else if(ch == 'L' || ch == 'l') {
scheduler = new LeastJob();
}else if (ch == 'P' || ch == 'p') {
scheduler = new PriorityAllocation();
}else {
System.out.println("지원되지않는 형식");
return;
}
scheduler.getNextCall();
scheduler.sendCallToAgent();
}
}
여기서 만약 vip는 대기없이 받는 새로운 시나리오를 추가적으로 만들시
Scheduler 인터페이스를 이용하여 클래스의 구현방법몰라도 인터페이스에서 선언된 매개변수, 반환 값 보고 클래스를 사용할 수 있다.
1.인터페이스 상수
2.디폴트 메서드 - default
3.정적 메서드 - static
4.private 메서드
public interface Calc {
double PI = 3.14; // 인터페이스에서 선언한 변수는 컴파일 과정에서 상수로 변함
int Error = -999999;
int add(int num1, int num2); // 인터페이스에서 선언한 메서드는 추상 메서드로 변함
int substract(int num1, int num2);
int divide(int num1, int num2);
int multiply(int num1, int num2);
int square(int num1);
// 디폴트 메서드 : 인터페이스에서 구현 코드까지 작성한 메서드
// 하위클래스에서 재정의 가능
default void description() {
System.out.println("정수 계산기 구현");
myMethod(); // 디폴트 메서드에서 private 메서드 호출
}
// 정적 메서드 : 인스턴스 생성과 상관없이 사용할 수 있는 메서드
static int total(int[] arr) {
int total = 0;
for(int i : arr) {
total += i;
}
myStaticMethod();
return total;
}
private void myMethod() { // private 메서드
System.out.println("private 메서드");
}
private static void myStaticMethod() { // private static 메서드
System.out.println("private static 메서드");
}
}
public class CalcMain {
public static void main(String[] args) {
CompleteCalc calc = new CompleteCalc();
int num1 = 10, num2 = 20;
System.out.println(calc.add(num1, num2));
System.out.println(calc.substract(num1, num2));
System.out.println(calc.divide(num1, num2));
System.out.println(calc.multiply(num1, num2));
System.out.println(calc.square(num1));
calc.showInfo();
//디폴트 메서드 ( 디폴트 메서드를 사용할라면 인스턴스를 만들어줘야함)
calc.description();
//정적메서드 사용하기
int[] arr = {1, 2, 3, 4, 5};
System.out.println(Calc.total(arr));
}
}
- 하나의 클래스가 여러 인터페이스 구현하는 경우
상속과 다르게 인터페이스는 여러개를 받을 수 있다 .
만약 두 인터페이스의 디폴트 메서드가 중복되는경우
그 인터페이스들을 상속받는 클래스에서 재정의 하면된다.
- 인터페이스 상속
인터페이스는 인터페이스를 상속할 수 있다.
- 인터페이스 구현과 클래스 상속 함께 쓰기
Queue 인터페이스 와 Shelf 클래스를 이용한 BookShelf 만들기
import java.util.ArrayList;
public class Shelf {
protected ArrayList<String> shelf;
public Shelf() {
shelf = new ArrayList<String>();
}
public ArrayList<String> getShelf() {
return shelf;
}
public int getCount() {
return shelf.size();
}
}
public interface Queue {
void enQueue(String title);
String deQueue();
int getSize();
}
public class Bookshelf extends Shelf implements Queue {
@Override
public void enQueue(String title) {
shelf.add(title);
}
@Override
public String deQueue() {
// TODO Auto-generated method stub
return shelf.remove(0);
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return getCount();
}
}
public class BookTest {
public static void main(String[] args) {
Bookshelf b1 = new Bookshelf();
b1.enQueue("사랑해요");
b1.enQueue("사랑해요2");
System.out.println(b1.getSize());
System.out.println(b1.deQueue());
System.out.println(b1.deQueue());
Queue shelfQueue = new Bookshelf(); // 업케스팅
shelfQueue.enQueue("태백산맥 1");
shelfQueue.enQueue("태백산맥 2");
shelfQueue.enQueue("불백산맥");
System.out.println(shelfQueue.deQueue());
System.out.println(shelfQueue.deQueue());
System.out.println(shelfQueue.deQueue());
}
}