명세
(specification)메서드 명세
만 보고 이를 구현한 클래스를 사용할 수 있음다형성
package ch14;
public interface Calc {
// 모든 변수는 상수로 변환됨 public static final
double PI = 3.14;
int ERROR = -99999999;
// 선언된 모든 메서드는 추상 메서드 public abstract
int add(int num1, int num2);
int subtract(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 메서드
// 인터페이스를 구현한 클래스에서 사용하거나 재정의 할 수 없음
// 인터페이스 내부에서만 사용하기 위해 구현하는 메서드
private void myMethod() {
System.out.println("myMethod");
}
private static void myStaticMethod() {
System.out.println("myStaticMethod");
}
}
Calculator와 CompleteCalc에서 인터페이스 구현
// Calculator.java
package ch14;
public abstract class Calculator implements Calc {
@Override
public int add(int num1, int num2) {
return num1 + num2;
}
@Override
public int subtract(int num1, int num2) {
return num1 - num2;
}
}
//CompleteCalc.java
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("CompleteCalc overriding");
}
}
package ch14;
public class CalculatorTest {
public static void main(String[] args) {
int num1 = 10;
int num2 = 2;
CompleteCalc calc = new CompleteCalc();
System.out.println(calc.add(num1, num2));
System.out.println(calc.subtract(num1, num2));
System.out.println(calc.times(num1, num2));
System.out.println(calc.divide(num1, num2));
calc.description();
// 인터페이스 .static 메서드 명 만으로 호출가능한 것 확인!
int [] arr = {1,2,3,4,5};
System.out.println(Calc.total(arr));
}
}
DAO(Data Acess Object)
는 데이터베이스에 접근하여 데이터를 생성, 조회, 수정 삭제하는 역할을 담당
하나의 인터페이스를 여러 객체가 구현하게 되면 클라이언트 프로그램은 인터페이스의 메서드를 활용하여 여러 객체의 구현을 사용할 수 있음 (다형성)
DB에 회원 정보를 넣는 dao(data access object)를 여러 DB 제품이 지원될 수 있게 구현함
환경파일(db.properties) 에서 database의 종류에 대한 정보를 읽고 그 정보에 맞게 dao 인스턴스를 생성하여 실행될 수 있게 함
<package.hierarchy>
//UserInfo.java(사용자 정보 클래스)
package ch13.domain.userinfo;
public class Userinfo {
private String userId;
private String passwd;
private String userName;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
// UserInfoDao.java ( dao 에서 제공되어야 할 메서드를 선언한 인터페이스 )
package ch13.domain.userinfo.dao;
// 같은 패키지가 아니기 때문에 import
import ch13.domain.userinfo.Userinfo;
public interface UserInfoDao {
void insertUserInfo(Userinfo userInfo);
void updateUserInfo(Userinfo userInfo);
void deleteUserInfo(Userinfo userInfo);
}
// UserInfoMySqlDao.java (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("Insert into MySQL DB userID = " + userInfo.getUserId());
}
@Override
public void updateUserInfo(Userinfo userInfo) {
System.out.println("Update into MySQL DB userID = " + userInfo.getUserId());
}
@Override
public void deleteUserInfo(Userinfo userInfo) {
System.out.println("delete into MySQL DB userID = " + userInfo.getUserId());
}
}
// UserInfoOracleDao.java (UserInfoDao 인터페이스를 구현한 Oracle 버전 dao)
package ch13.domain.userinfo.dao.oracle;
import ch13.domain.userinfo.Userinfo;
import ch13.domain.userinfo.dao.UserInfoDao;
public class UserInfoOracleDao implements UserInfoDao{
@Override
public void insertUserInfo(Userinfo userInfo) {
System.out.println("insert into ORACLE DB userId =" + userInfo.getUserId() );
}
@Override
public void updateUserInfo(Userinfo userInfo) {
System.out.println("update into ORACLE DB userId = " + userInfo.getUserId());
}
@Override
public void deleteUserInfo(Userinfo userInfo) {
System.out.println("delete from ORACLE DB userId = " + userInfo.getUserId());
}
}
// UserInfoClient.java (UserInfoDao 인터페이스를 활용하는 클라이언트 프로그램)
package ch13.userinfo.web;
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.UserInfoOracleDao;
public class UserInfoClient {
public static void main(String[] args) throws IOException {
//주어진 fis 객체가 파일을 바이트 스트림으로 읽기 위한 FileInputStream 객체 생성
FileInputStream fis = new FileInputStream("db.properties");
// key-value 값 담
//"Key = Value" 형태로 된 "파일이름.properties" 파일 또는 Xml 파일
// key를 주면 Value를 반환하는 기능을 가짐
Properties prop = new Properties();
prop.load(fis);
String dbType = prop.getProperty("DBTYPE");
Userinfo userInfo = new Userinfo();
userInfo.setUserId("12345");
userInfo.setPasswd("!@#@!#!");
userInfo.setUserName("Lee");
UserInfoDao userInfoDao = null;
if(dbType.equals("ORACLE")) {
userInfoDao = new UserInfoOracleDao();
}
else if(dbType.equals("MYSQL")) {
userInfoDao = new UserInfoMySqlDao();
}
else{
System.out.println("db support error");
return;
}
userInfoDao.insertUserInfo(userInfo);
userInfoDao.updateUserInfo(userInfo);
userInfoDao.deleteUserInfo(userInfo);
}
}
예시)
grand father 이라는 클래스가 있고 father1, father2 두개의 클래스가 상속을 받은 상황이라 가정
이후 f1,f2를 child가 상속 받음
GF에 a();라는 메서드가 있는데 이를 f1,f2에서 오버라이드 함
Child c = new Child;
c.a();
이 경우 어느 메서드를 호출해야 하는지 의문
따라서 자바는 이러한 문제를 만들지 않기 위해 단일 상속
package ch15;
public interface Buy {
void buy();
default void order() {
System.out.println("buy order");
}
}
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");
}
public void hello() {
System.out.println("Hello");
}
@Override
// buy것 대신 sell의 디폴트 메서드를 쓰겠다는 의미
public void order() {
Sell.super.order();
}
}
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;
// 재정의된 메서드가 호출됨으로 sell order 가 프린트 됨을 볼 수 있음.
buyer.buy();
buyer.order();
Sell seller = customer;
seller.sell();
seller.order();
}
}
// shelf.java
package ch16;
import java.util.ArrayList;
public class Shelf {
// 상속하여 사용하기 위해 protected
protected ArrayList<String> shelf;
public Shelf() {
shelf = new ArrayList<String>();
}
public ArrayList<String> getShelf(){
return shelf;
}
public int getCount() {
return shelf.size();
}
}
// Queue.java
package ch16;
public interface Queue {
void enQueue(String title);
String deQueue();
int getSize();
}
package ch16;
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();
}
}
// bookshelftest.java
package ch16;
public class BookShelfTest {
public static void main(String[] args) {
Queue bookQueue = new BookShelf();
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());
}
}