[1] 인터페이스 예시
(1) 인터페이스 & 추상클래스
- 인터페이스 + 추상클래스 선언
package ch11;
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);
}
하위 클래스에 메서드 재정의
package ch11;
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;
}
}
하위클래스에 메서드 재정의
package ch11;
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;}
return num1/num2 ;
}
public void showInfo() {
System.out.println("구현완료 ");
}
}
- 실행 클래스
package ch11;
public class CalculatorTest {
public static void main(String[] args) {
int num1 = 10;
int num2 = 2;
Calc calc = new CompleteCalc();
System.out.println(calc.add(num1, num2));
System.out.println(calc.substract(num1, num2));
System.out.println(calc.times(num1, num2));
System.out.println(calc.divide(num1, num2));
}
}
(2) DAO & DB & 인터페이스
DB에 회원 정보를 넣는 dao를 여러 DB 제품이 지원될 수 있게 구현함
환경파일(db.properties)에서 database의 종류에 대한 정보를 읽고
그 정보에 맞게 dao 인스턴스를 생성하여 실행될 수 있게 함
① 데이터베이스 환경파일 만들기
- Db.properties
- 반영할 데이터베이스를 읽는 환경파일이다
DBTYPE=ORACLE
② domain.userInfo 패키지에 UserInfo.java 클래스 파일을 만든다
private 보호해야하는 변수를 캡슐화한다
사용자 정보 클래스
package ch13.domain.userinfo;
public class UserInfo {
private String userId;
private String password;
private String userName;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
③ domain.userInfo 패키지 > dao 안에 인터페이스를 만든다
인터페이스 내용에는 회원정보가져오기(insertUserInfo) , 회원정보수정하기(updateUserInfo) , 회원정보삭제하기(deleteUserInfo)를 추상메서드로 넣는다
dao에서 제공되어야하는 메서드를 선언한 인터페이스
package ch13.domain.userinfo.dao;
import ch13.domain.userinfo.UserInfo;
public interface UserInfoDao {
void insertUserInfo(UserInfo userInfo);
void updateUserInfo(UserInfo userInfo);
void deleteUserInfo(UserInfo userInfo);
}
④ 인터페이스의 추상메서드를 재정의할 클래스를 만든다
domain.userInfo 패키지 > dao > MySQL
domain.userInfo 패키지 > dao > Oracle
데이터베이스 종류는 2가지로 추상메서드를 재정의하는 클래스를 각각 만든다
UserInfoDao 인터페이스를 구현한 MySql 버전 dao
package ch13.domain.userinfo.dao.mysql;
import ch13.domain.userinfo.UserInfo;
import ch13.domain.userinfo.dao.UserInfoDao;
public class UserInfoMySqlDao implements UserInfoDao {
@Override
public void insertUserInfo(UserInfo userInfo) {
System.out.println("MySQL DB 의 userID 는 " + userInfo.getUserId());
}
@Override
public void updateUserInfo(UserInfo userInfo) {
System.out.println("MySQL DB 의 userID 는 " + userInfo.getUserId());
}
@Override
public void deleteUserInfo(UserInfo userInfo) {
System.out.println("MySQL DB 의 userID 는 " + userInfo.getUserId());
}
}
UserInfoDao 인터페이스를 구현한 Oracle 버전 dao
package ch13.domain.userinfo.dao.oracle;
import ch13.domain.userinfo.UserInfo;
import ch13.domain.userinfo.dao.UserInfoDao;
public class UserInfoOracle implements UserInfoDao {
@Override
public void insertUserInfo(UserInfo userInfo) {
System.out.println(" Oracle DB 의 userID 는 " + userInfo.getUserId());
}
@Override
public void updateUserInfo(UserInfo userInfo) {
System.out.println(" Oracle DB 의 userID 는 " + userInfo.getUserId());
}
@Override
public void deleteUserInfo(UserInfo userInfo) {
System.out.println(" Oracle DB 의 userID 는 " + userInfo.getUserId());
}
}
UserInfoDao 인터페이스를 구현한 MySql 버전 dao
⑤ 웹에서 동작하는 실행 클래스를 만든다
UserInfoDao 인터페이스를 활용하는 클라이언트 프로그램
package ch13.web.userinfo;
import java.io.FileInputStream;
public class UserInfoClient {
public static void main(String[] args) {
//DB파일을 읽는다 , import 한다
FileInputStream fis = new FileInputStream("db.properties");
}
}
package ch13.web.userinfo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class UserInfoClient {
public static void main(String[] args) throws FileNotFoundException {
//DB파일을 읽는다 .import하면 throw 내용이 추가된다
FileInputStream fis = new FileInputStream("db.properties");
}
}
package ch13.web.userinfo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Properties;
public class UserInfoClient {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream fis = new FileInputStream("db.properties");
//db.procperties 파일을 (왼쪽 = 오른쪽) 정보값을 쌍으로 가지고 오는 변수
Properties prop = new Properties();
//파일을 읽는다 import하면
prop.load(fis);
}
}
package ch13.web.userinfo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class UserInfoClient {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("db.properties");
Properties prop = new Properties();
prop.load(fis);
//throws 값이 바뀐다
}
}
package ch13.web.userinfo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import ch13.domain.userinfo.UserInfo;
import ch13.domain.userinfo.dao.UserInfoDao;
import ch13.domain.userinfo.dao.mysql.UserInfoMySqlDao;
import ch13.domain.userinfo.dao.oracle.UserInfoOracle;
public class UserInfoClient {
public static void main(String[] args) throws IOException {
//DB파일을 읽는다
FileInputStream fis = new FileInputStream("db.properties");
Properties prop = new Properties();
prop.load(fis);
String dbType = prop.getProperty("DBTYPE");
//회원정보 반영을 위한 인스턴스 생성 및 정보 입력
UserInfo userInfo = new UserInfo();
userInfo.setUserId("12345");
userInfo.setPassword("!@#$%");
userInfo.setUserName("이순신");
// dao 속성으로 생성했으나 값은 없다 . import 해서 인터페이스타입으로 생성한다
UserInfoDao userInfoDao = null;
}
}
package ch13.web.userinfo;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import ch13.domain.userinfo.UserInfo;
import ch13.domain.userinfo.dao.UserInfoDao;
import ch13.domain.userinfo.dao.mysql.UserInfoMySqlDao;
import ch13.domain.userinfo.dao.oracle.UserInfoOracle;
public class UserInfoClient {
public static void main(String[] args) throws IOException {
//DB파일을 읽는다
FileInputStream fis = new FileInputStream("db.properties");
Properties prop = new Properties();
prop.load(fis);
String dbType = prop.getProperty("DBTYPE");
//회원정보 반영을 위한 인스턴스 생성 및 정보 입력
UserInfo userInfo = new UserInfo();
userInfo.setUserId("12345");
userInfo.setPassword("!@#$%");
userInfo.setUserName("이순신");
// dao 속성을 가진 객체 생성했으나 값은 없다
UserInfoDao userInfoDao = null;
//DB파일의 종류가 어떤것일때 어떤 dao클래스를 반영할건지 조건문을 만든다
if(dbType.equals("ORACLE")){
userInfoDao = new UserInfoOracle();
}
else if(dbType.endsWith("MYSQL")){
userInfoDao = new UserInfoMySqlDao();
}
else{
System.out.println("db support error");
return;
}
// 조건문에 해당하는 dao속성을 가진 객체의 정보를 조회하라
userInfoDao.insertUserInfo(userInfo);
userInfoDao.updateUserInfo(userInfo);
userInfoDao.deleteUserInfo(userInfo);
}
}
(3) static 메서드 & default 메서드
- 인터페이스
package ch14;
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 num : arr) {
total += num;
}
myStaticMethod();
return total;
}
private void myMethod() {
System.out.println("myMethod");
}
private static void myStaticMethod() {
System.out.println("myStaticMethod");
}
}
인터페이스의 추상메서드 클래스
package ch14;
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;
}
}
하위클래스
인터페이스의 메서드를 재정의함
package ch14;
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;}
return num1/num2 ;
}
public void showInfo() {
System.out.println("구현완료 ");
}
@Override
public void description() {
System.out.println("Overriding");
}
}
실행 클래스
package ch14;
public class CalculatorTest {
public static void main(String[] args) {
int num1 = 10;
int num2 = 2;
Calc calc = new CompleteCalc();
System.out.println(calc.add(num1, num2));
System.out.println(calc.substract(num1, num2));
System.out.println(calc.times(num1, num2));
System.out.println(calc.divide(num1, num2));
calc.description();
int[] arr = { 4 ,5,6,7,8};
System.out.println(Calc.total(arr));
}
}
(4) 인터페이스 & defualt 메서드 & static 메서드 예시
public class HelloJava {
public static void main(String[] args) {
Child c = new Child();
c.play();
c.play2();
interAface.play3();
interBface.play3();
}
}
class Child extends Parents implements interAface, interBface {
@Override
public void play() {
System.out.println("인터페이스가 연결된 하위클래스의 메서드 ");
}
}
class Parents {
public void play2() { System.out.println("상위클래스의 메서드2 ");}
}
interface interAface {
default void play() { System.out.println("인터페이스1에 메서드1");}
default void play2() { System.out.println("인터페이스1에 메서드2");}
static void play3() { System.out.println("인터페이스1의 static메서드1");}
}
interface interBface {
default void play() { System.out.println("인터페이스2의 메서드1");}
static void play3() { System.out.println("인터페이스2의 static메서드1");}
}
(5) 2개이상의 인터페이스 사용하기
- 디폴트 메서드가 인터페이스1에도 있고 인터페이스2에도 있다면 중복 되기 때문에 구현 하는 클래스에서도 재정의 해야한다
- 여러 인터페이스를 구현한 클래스는 인터페이스 타입으로 형 변환 되는 경우 해당 인터페이스에 선언된 메서드만 사용 가능 함
인터페이스 1번 Buy
package ch15;
public interface Buy {
void buy();
default void order() {
System.out.println( "buy order ");
}
}
인터페이스 2번 Sell
package ch15;
public interface Sell {
void sell();
default void order() {
System.out.println(" sell order ");
}
}
인터페이스의 추상메서드가 재정의 된 클래스 파일
package ch15;
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() {
System.out.println("customer order ");
}
public void hello() {
System.out.println("hello");
}
}
실행클래스
package ch15;
public class CustomerTest {
public static void main(String[] args) {
Customer customer = new Customer();
customer.buy();
customer.sell();
customer.order();
customer.hello();
Buy buyer = customer;
buyer.buy();
buyer.order();
Sell seller = customer;
seller.sell();
seller.order();
}
}
(6) 클래스 상속 & 인터페이스
- 실무에서 프레임워크나 오픈소스와 함께 연동되는 구현을 하게 되면 클래스 상속과 인터페이스의 구현을 같이 사용하는 경우가 많음
- 책이 순서대로 대여가 되는 도서관 구현
- 책을 보관하는 자료 구조가 Shelf에 구현됨 (ArrayList)
- Queue 인터페이스를 구현함
- Shelf 클래스를 상속 받고 Queue를 구현한다.
인터페이스
package ch15;
public interface Queue {
void enQueue(String title);
String deQueue();
int getSize();
}
상위 클래스
package ch15;
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();
}
}
인터페이스와 상위클래스를 상속받는 클래스
package ch15;
public class BookSheIf 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();
}
}
실행 클래스
package ch15;
public class BookShelfTest {
public static void main(String[] args) {
Queue bookQueue = new BookSheIf();
bookQueue.enQueue("책1");
bookQueue.enQueue("책2");
bookQueue.enQueue("책3");
bookQueue.enQueue("책4");
bookQueue.enQueue("책5");
System.out.println(bookQueue.getSize());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
System.out.println(bookQueue.deQueue());
}
}
(7) 추상클래스와 템플릿 메서드 예시
Player가 있고 Player는 GameLevel 속성을 가집니다.
각 GameLevel 단계 마다 run(), jump(), turn() 세 가지 기능이 업그레이드 됩니다.
초보자 레벨 : 천천히 달립니다. run() 만 가능
중급자 레벨 : 빠르게 달리고, 점프할 수 있습니다. run(), jump() 가능
고급자 레벨 : 엄청 빠르게 달리고, 높게 점프하고, 턴할 수 있습니다. run(), jump(), turn() 가능
Player는 한번에 하나의 레벨 상태만을 가질 수 있습니다.
Player가 play() 중에 레벨에 있는 go(int count) 라는 메서드를 호출하면
run() 하고 count 횟수 만큼 jump() 하고 turn() 합니다.
다음 클래스 다이어그램을 참고하여 각 레벨에서 go() 가 호출 될때 다음과 같이 출력 되도록 하세요
(8) 인터페이스를 활용하는 고객센터
고객 센터에 전화 상담을 하는 상담원들이 있습니다.
일단 고객에게서 전화가 오면 대기열에 저장되고 각 상담원에게 배분이 됩니다.
배분이 되는 정책은 크게 세 가지가 있습니다.
모든 상담원이 동일한 상담 건수를 처리하도록 상담원 순서대로 배분합니다.
쉬고 있거나 상담원에게 할당된 통화 수가 가장 적은 상담원에게 배분합니다.
고객의 등급에 따라 등급이 높은 고객은 업무능력이 우수한 상담원에게 배분합니다.
세 가지 정책은 필요에 따라 바뀌어 운영될 수 있습니다.
다음 클래스 다이어그램을 참고하여 각 배분 규칙이 적용되도록 구현해 보세요
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();
}
else if ( ch == 'P' || ch =='p') {
scheduler = new PriorityAllocation();
}
else {
System.out.println("지원되지 않는 기능입니다.");
return;
}
scheduler.getNextCall();
scheduler.sendCallToAgent();
}
}
'🌈 백엔드 > 객체 지향' 카테고리의 다른 글
JAVA_객체지향_제네릭 프로그래밍 (0) | 2023.06.19 |
---|---|
JAVA_객체지향_ Class 클래스 (0) | 2023.06.19 |
JAVA_객체지향_인터페이스 (2) | 2023.06.18 |
JAVA_객체지향_추상클래스 & 가상메서드 (0) | 2023.06.18 |
JAVA_객체지향_다형성 & 업캐스팅 & 다운캐스팅 (0) | 2023.06.18 |
댓글