[Java]공부 10. interface

ohjihyung·2022년 6월 23일
0
post-thumbnail

인터페이스란?

class or 프로그램이 제공하는 기능을 명시적으로 선언하는 역할
추상메서드와 상수로만 이루어져있어 인스턴스를 생성할 수 없다

인터페이스를 이용하여 계산기 만들기

Calc 인터페이스

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 메서드");
	 }
}

Calculator 추상클래스

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 추상 클래스");
	}

}

CompleteCalc 클래스

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()를 만든다.

Scheduler 인터페이스

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));
	}
}

인터페이스 활용하기

  1. 하나의 클래스가 여러 인터페이스 구현하는 경우
    상속과 다르게 인터페이스는 여러개를 받을 수 있다 .
    만약 두 인터페이스의 디폴트 메서드가 중복되는경우
    그 인터페이스들을 상속받는 클래스에서 재정의 하면된다.
  1. 인터페이스 상속
    인터페이스는 인터페이스를 상속할 수 있다.
  1. 인터페이스 구현과 클래스 상속 함께 쓰기
    Queue 인터페이스 와 Shelf 클래스를 이용한 BookShelf 만들기

shelf 클래스

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();
	}
	
}

Queue 인터페이스

public interface Queue {
	void enQueue(String title);
	String deQueue();
	int getSize();
}

BookShelf 클래스

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();
	}

}

main

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());
	}
}
profile
웹 개발자의 기초부터 심화까지

0개의 댓글