//. 인터페이스란?
| 인터페이스의 요소
추상 메서드
상수
디폴트 메서드
정적 메서드
private 메서드
| 인터페이스 선언과 구현
public interface Calc
{
// 인터페이스에서 선언한 변수는 컴파일 과정에서 상수로 변환됨
double PI = 3.14;
int ERROR = –9999999;
// 인터페이스에서 선언한 메서드는 컴파일 과정에서 추상 메서드로 변환됨
int add(int num1, int num2);
int substract(int num1, int num2);
int times(int num1, int num2);
int divide(int num1, int num2);
}
Calc ( Interface ) |
⬆ |
Calculator ( Abstract Class ) |
⬆ |
CompleteCalc ( Concrete Class ) |
- 메서드를 선언할 수 있을 때
함수의 반환값, 이름, 매개 변수까지를 해서 함수의 시그니처라고 부름
/// Calc.java ///
package interfacex;
public interface Calc
{
double PI = 3.14;
int ERROR = -9999999;
int add(int num1, int num2);
int substract(int num1, int num2);
int times(int num1, int num2);
int divide(int num1, int num2);
}
/// Calculator.java ///
package interfacex;
// 추상 메서드를 모두 구현하지는 않았기 때문에 abstract 클래스로 남는 것
public abstract class Calculator implements Calc
{
@override
public int add(int num1, int num2)
{
return num1 + num2;
}
@override
public int substract(int num1, int num2)
{
return num1 - num2;
}
}
/// CompleteCalc.java ///
package interfacex;
public class CompleteCalc extends Calculator
{
@override
public int times(int num1, int num2)
{
return num1* num2;
}
@override
public int divide(int num1, int num2)
{
if ( num2==0 )
return ERROR;
else
return num1/num2;
}
public void showInfo()
{
System.out.println(“모두 구현하였습니다”);
}
}
/// CalcTest.java ///
package interfacex;
public class CalcTest
{
public static void main(String[] args)
{
CompleteCalc calc = new CompleteCalc();
int n1 = 10;
int n2 = 10;
System.out.println(calc.add(n1,n2));
System.out.println(calc.substract(n1,n2));
System.out.println(calc.times(n1,n2));
System.out.println(calc.divide(n1,n2));
calc.showInfo();
}
}
- 모두 구현된 클래스는 CompleteCalc 밖에 없기 때문에
new할 수 있는 것도 그것뿐임
But 클래스(앞쪽)은 Calc, Calculator도 다 됌 ( 하위이기 때문에 )
But 인터페이스 타입으로 변수 선언시 showInfo 같은 것은 다운캐스팅 후 사용
| 타입 상속과 형 변환
Calc calc = new CompleteCalc();
인터페이스를 구현한 클래스는 인터페이스 타입으로 변수를 선언하여
인스턴스를 생성할 수 있음
인터페이스는 구현 코드가 없기 때문에 타입 상속이라고도 함
—------------------—------------------—------------------—------------------—------------------—---------------
—------------------—------------------—------------------—------------------—------------------—---------------
// 인터페이스를 활용한 다형성 구현 - 1 & 2
| 인터페이스의 역할
인터페이스는 클라이언트 프로그램에 어떤 메서드를
제공하는지 알려주는 명세(Specification) 또는 약속
한 객체가 어떤 인터페이스의 타입이라 함은
그 인터페이스의 메서드를 구현했다는 의미
클라이언트 프로그램은 실제 구현 내욜을 몰라도
인터페이스의 정의만 알면 그 객체를 사용할 수 있음
인터페이스를 구현해 놓은 다양한 객체를 사용함 - 다형성
: JDBC를 구현한 오라클, MSSQL 라이브러리
인터페이스가 코드가 없지만 설계에서 중요한 청사진이다.
인터페이스는 디폴트 메서드, 정적 메서드를 제외하고는 껍데기이다.
추상클래스와의 차이는 공통되는 모듈이 있을수도 있고, 없을수도 있고
BUT 인터페이스는 순수하게 명세만 되어있기 때문에 여러 개를 상속 받을 수 있다.
Ex_DetailedDescription)
JDBC(=Java DataBase Connectivity)
JDBC는 자바와 DB를 연결해서 어떻게 쓸 것인지 정의한 내용
자바에서 DB를 쓰려면 Connection, Statement, Resultset 등등이 필요할텐데
이것들을 쓰려면 Interface의 형태로 나와있기 때문에
다양한 메서드를 정의(구현)해야하는데 이것을 하는 것들은
Oracle, MySQL, MSSQL등의 DB사들이 구현을 한다.
구현을 해서 주는 것이 라이브러리(.jar(=라이브러리))
고로 Oracle로 연결을 해서 어떤 쿼리문을 이용한다고 하면
Oracle에서 제공하는 라이브러리 내에 있는 Interface에 있는
메서드(구현된)를 쓰는 것
| 인터페이스의 다형성 구현하기 / 코딩해보기
고객 센터에 전화 상담을 하는 상담원들이 있다.
일단 고객 센터로 전화가 오면 대기열에 저장된다.
상담원이 지정되기 전까지 대기 상태가 된다.
각 전화가 상담원에게 배분되는 정책은 다음과 같이 여러 방식으로 구현된다.
- 상담원 순서대로 배분하기
- 대기가 짧은 상담원 먼저 배분하기
- 우선순위가 높은(숙련도가 높은) 상담원에게 먼저 배분하기
위와 같은 다양한 정책이 사용되는 경우 Interface를 정의하고
다양한 정책을 구현하여 실행하세요
/// Scheduler.java ///
package scheduler;
public interface Scheduler
{
public void getNextCall();
public void sendCallToAgent();
}
/// RoundRobin.java ///
package scheduler;
public class RoundRobin implements Scheduler
{
@override
public void getNextCall()
{
System.out.println(“상담 전화를 순서대로 대기열에서 가져옵니다”);
}
@override
public void sendCallToAgent()
{
System.out.println(“다음 순서의 상담원에게 배분합니다”);
}
}
/// LeastJob.java ///
package scheduler;
public class LeastJob implements Scheduler
{
@override
public void getNextCall()
{
System.out.println(“상담 전화를 순서대로 대기열에서 가져옵니다”);
}
@override
public void sendCallToAgent()
{
System.out.println(“현재 상담 업무가 없거나 상담 대기가 가장 적은 상담원에게 할당합니다”);
}
}
/// PriorityAllocation.java ///
package scheduler;
public class LeastJob implements Scheduler
{
@override
public void getNextCall()
{
System.out.println(“고객 등급이 높은 고객의 Call을 먼저 가져옵니다”);
}
@override
public void sendCallToAgent()
{
System.out.println(“업무 숙련도가 높은 상담원에게 먼저 배분합니다”);
}
}
/// SchedulerTest.java ///
package scheduler;
public class SchedulerTest
{
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();
}
if ( ch == ‘P’ || ch == ‘p’ )
{
scheduler = new.PriorityAllocation();
}
else
{
System.out.println(“지원하지 않는 기능입니다”);
return;
}
scheduler.getNextCall();
scheduler.sendCallToAgent();
}
}
| 인터페이스와 strategy pattern
인터페이스를 활용하면 다양한 정책이나 알고리즘을
프로그램의 큰 수정 없이 적용, 확장할 수 있음
Sorting | ||
⬆ | ⬆ | ⬆ |
Bubble Sort | Quick Sort | Heap Sort |
| 인터페이스의 사용 예
UserInfoWeb | > uses > | IUserInfoDao | ||
⬆ implements ⬆ | ||||
oracleDao | mysqlDao | mssqlDao |
—------------------—------------------—------------------—------------------—------------------—---------------
—------------------—------------------—------------------—------------------—------------------—---------------
// 인터페이스의 요소들 1 & 2
/ 인터페이스의 요소들 - 1
| 인터페이스의 요소
상수 :
선언된 모든 변수는 상수로 처리 됨
메서드 :
모든 메서드는 추상 메서드
디폴트 메서드 :
기본 구현을 가지는 메서드
구현하는 클래스에서 재정의 할 수 있음
정적 메서드 :
인스턴스 생성과 상관없이 인터페이스 타입으로 호출하는 메서드
private 메서드 :
인터페이스 내에서 사용하기 위해 구현한 메서드
구현하는 클래스에서 재정의 할 수 없음
2가지 종류 : 일반 메서드, static 메서드
| 여러 개의 인터페이스 구현하기
인터페이스는 구현 코드가 없으므로 하나의 클래스가 여러 인터페이스를 구현할 수 있음
디폴트 메서드의 이름이 중복 되는 경우에는 재정의 함
Buy (인터페이스) |
Sell (인터페이스) |
⬆ | ⬆ |
Customer (실제 구현 클래스) |
| 인터페이스 상속
인터페이스 간에도 상속이 가능함
구현이 없으므로 extends 뒤에 여러 인터페이스를 상속받을 수 있음
구현 내용이 없으므로 타입 상속(type inheritance)라고 함
X | Y |
x() | y() |
⬆ | ⬆ |
MyInterface | |
myMethod() | |
⬆ implements ⬆ | |
MyClass |
| 인터페이스 구현과 클래스 상속 함께 사용하기
Shelf | Queue |
⬆ extends ⬆ | ⬆ implements ⬆ |
BookShelf |
—————
public class BookShelf extends Shelf implements Queue
{
// 배열에 요소 추가
@Override
public void enQueue(String title)
{
shelf.add(title);
}
// 맨 처음 요소를 배열에서 삭제하고 반환
@Override
public String deQueue()
{
return shelf.remove(0);
}
// 배열 요소 개수 반환
@Override
public int getSize()
{
return getCount();
}
}
—————
/// Calc.java ///
package interfacex;
public interface Calc
{
double PI = 3.14;
int ERROR = -9999999;
int add(int num1, int num2);
int substract(int num1, int num2);
int times(int num1, int num2);
int divide(int num1, int num2);
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 method”);
}
private static void myStaticMethod()
{
System.out.println(“private static method”);
}
}
/// CalcTest.java ///
package interfacex;
public class CalcTest
{
public static void main(String[] args)
{
CompleteCalc calc = new CompleteCalc();
int n1 = 10;
int n2 = 10;
System.out.println(calc.add(n1,n2));
System.out.println(calc.substract(n1,n2));
System.out.println(calc.times(n1,n2));
System.out.println(calc.divide(n1,n2));
calc.showInfo();
calc.description();
int[] arr = {1,2,3,4,5,}
int sum = Calc.total(arr);
System.out.println(sum);
}
}
| 여러 개의 인터페이스 구현하기 / 코딩 예
/// Buy.java ///
package interfacex;
public interface Buy
{
void buy();
default void order()
{
System.out.println(“구매 주문”);
}
}
/// Sell.java ///
package interfacex;
public interface Sell
{
void sell();
default void order()
{
System.out.println(“판매 주문”);
}
}
/// Customer.java ///
package interfacex;
public class Customer implements Buy, Sell
{
@Override
public void sell()
{
System.out.println(“customer sell”);
}
@Override
public void buy()
{
System.out.println(“customer buy”);
}
@Override
public void order()
{
/// 방법 1~3중 하나 택
/// 방법1. Buy의 order()을 쓰겠다
Buy.super.order();
/// 방법2. Sell의 order()을 쓰겠다
Sell.super.order();
/// 방법3. 재정의
System.out.println(“ customer orders”);
}
}
/// CustomerTest.java ///
package interfacex;
public class CustomerTest
{
public static void main(String[] args)
{
Customer customer = new Customer();
customer.buy();
customer.sell();
customer.order();
customer.sayHello();
/// Buy 타입으로 customer가 되면,
///호출 가능은 자기 메서드뿐(buy, order(=인터페이스의 order_다형성))
Buy buyer = customer;
buyer.order();
/// Sell 타입으로 customer가 되면
/// 호출 가능은 자기 메서드뿐(sell, order(=인터페이스의order_다형성))
Sell seller = customer;
seller.order():
/// 다운캐스팅도 가능하다
}
}
—------------------—------------------—------------------—------------------—------------------—---------------
/ 인터페이스의 요소들 - 2
2개의 인터페이스( X, Y )를 상속받고(MyInterface)
구현한다(myClass)
- (MyClass)는 (MyInterface)이기도 하지만 (X)이기도 하고 (Y)이기도 하다
> 타입 상속 (type inheritance)
/// X.java ///
package interfacex;
public interface X
{
void x();
}
/// Y.java ///
package interfacex;
public interface Y
{
void y();
}
/// MyInterface.java ///
package interfacex;
public interface MyInterace extends X,Y
{
void myMethod();
}
/// MyClass.java ///
package interfacex;
public class MyClass implements MyInterface
{
@Override
public void X()
{
/// 작동 코드 ///
}
@Override
public void Y()
{
/// 작동 코드 ///
}
@Override
public void MyMethod()
{
/// 작동 코드 ///
}
}
| 인터페이스 구현과 클래스 상속 함께 사용하기 / 코딩
Shelf | Queue |
⬆ extends ⬆ | ⬆ implements ⬆ |
BookShelf |
/// Shelf.java ///
package interfacex;
public class Shelf
{
protected ArrayList<String> shelf;
public Shelf()
{
shelf = new ArrayList<String>();
}
public ArrayList<String> getShelf()
{
return shelf;
}
public ArrayList<String> getCount()
{
return shelf.size();
}
}
/// Queue.java ///
package interfacex;
public interface Queue
{
void enQueue(String title);
String deQueue;
int getSize();
}
/// BookShelf.java ///
package interfacex;
public class BookShelf extends Shelf implements Queue
{
@Override
public void enQueue(String title)
{
shelf.add(title);
}
@Override
public deQueue()
{
return shelf.remove(0);
}
@Override
public int getSize(String title)
{
return getCount();
}
}
/// BookShelfTest.java ///
package interfacex;
public class BookShelfTest
{
public static void main(String[] args)
{
Queue bookQueue = new BookShelf();
bookQueue.enQueue(“태백산맥 1”);
bookQueue.enQueue(“태백산맥 2”);
bookQueue.enQueue(“태백산맥 3”);
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
}
}
—------------------—------------------—------------------—------------------—------------------—---------------
—------------------—------------------—------------------—------------------—------------------—---------------
// 코딩해 보세요
| 정렬 알고리즘 구현하기
다음과 같이 여러 정렬 구현 알고리즘이 입력에 따라 실행될 수 있도록 구현해 보세요
구현할 것)
Sort |
ascending(int[]) descending(int[]) description() |
⬆ implements ⬆ | ||
QuickSort | HeapSort | BubbleSort |
출력 화면)
정렬방식을 선택하세요.
B : BubbleSort
H : HeapSort
Q : QuickSort
( Q )를 입력한 경우 |
QuickSort ascending
QuickSort descending
숫자를 정렬하는 알고리즘입니다
QuickSort입니다
—-----------—-----------—-----------—-----------—-----------—-----------—-----------—-----------
—-----------—-----------—-----------—-----------—-----------—-----------—-----------—-----------
이 정리 내용은 패스트 캠퍼스, K-Digital Credit Java 강의를 참고했습니다