본문 바로가기
🌈 백엔드/객체 지향

JAVA_객체지향_인터페이스 예시

by 개발자 알마 2023. 6. 19.
반응형

 

 

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

}

 

반응형

댓글