Interface(인터페이스)

JK·2022년 12월 23일
0

JAVA

목록 보기
15/28
post-thumbnail

Interface

1. 인터페이스란

- 작업명세서
  - 실제로 구현된 것이 없는 기본 설계도
  - 객체 생성 불가, 클래스 작성 시 꺼내 쓴다고 보면 된다
  - 미리 정해진 규칙에 맞게 구현하도록 표준을 제시
  - 추상메소드와 상수만 가능

- 다형성 
  - 하나의 객체를 많은 타입으로 생성 가능
Class S{
			...
			public void method(){…}
		}
Class C extends S {
			...
			public void method(){…}
		}
		C c = new C()		//C에서의 c
		S s1 = new C();		//C에서의 s1
		S s2 = new S();		//S에서의 s2
		s1.method(); 
s2.method();
- 객체를 부속품화 : 다양한 객체를 마음대로 변경 가능

2. 문법

- class 대신 interface 사용
- 추상메소드와 상수만 존재
public interface 인터페이스이름 {
		public static final 타입 상수이름 = 값;
		public abstract 메소드 이름(매개변수 목록);  //구현된 메소드는 가질 수 없다
	}
	//모든 멤버변수는 public static final이어야하며 static final은 생략할 수 있다.'
	//모든 메서드는 public abstract 이어야 하며, abstract를 생략할 수 있다.
- private는 불가 : 상수나 메소드를 만들 때 private 접근 제한자는 불가
- 변수 타입 : 인터페이스는 객체를 생성할 수 없다. 다만, 변수 타입으로만 사용 됩니다.
- 구현은 Implement 되는 클래스에서 가능

3. 다형성

  • 다형성이란? 여러가지 형태를 가질 수 있는 능력 -> 객체가 여러가지로 변할 수 있다
  • 하나의 인터페이스를 사용하여 다양한 구현 방법 제공
  • 오버로딩(overloading) : 같은 클래스 내에서만 오버로딩이라 할 수 있다.
  • 메소드 overriding(다중정의) : 같은 이름을 가진 메소드를 다른 클래스에서 재정의 하는 법
   - overriding 조건 1. 선언부가 같아야 한다(이름, 매개변수, 리턴타입)
   				    2. 접근제어자를 같거나 넓게 사용하여야 한다. private>protected>public 
                    
 ※ 오버로딩 vs. 오버라이딩
 
	오버로딩(overloading) : 컴파일러 입장에서는 기존에 없는 새로운 메서드를 정의하는 것(new)
			              메소드 다중정의 (같은 class에서 동일한 메소드가 매개변수를 달리 여러 개 존재
                          
	오버라이딩(overriding): 상속받은 메서드의 내용을 변경하는 것(change, modify)
			메소드 재정의 : 부모클래스와 자식클래스에 동일한 method 존재(틀만 가져와 재정의)

4. 인터페이스와 다중상속

  • java는 다중상속 불가 하지만 interface를 통하여 다중구현이 가능하다
  1. 단일상속(O)
public class ChildClass extends ParentClass1 {

} 
  1. 다중상속(X)
public class ChildClass extends ParentClass1, ParentClass2, ParentClass3 {

}
  1. 다중구현(O)
public class ChildClass implements IFunction1, IFunction2, IFunction3 {

}

5. 인터페이스의 장점

  1. 개발시간 단축 가능
  2. 표준화 가능 : 기본 틀을 인터페이스로 사용
  3. 서로 관계없는 클래스들을 연결할 수 있다
  4. 독립적 프로그래밍 가능

6. 인터페이스와 추상클래스

(공통점)
1. 추상메소드를 가지고 있다 - 추상메소드를 가지고 있어 하위 클래스에서 구현해야 한다.
2. 변수 타입이 목적 - 객체생성이 목적이 아닌 변수 타입을 정의하는 것이 목적.
3. 객체 생성 불가. anonymose(익명클래스)를 이용할 수 있다.

(차이점)
1. 상속, 구현 - 추상메소드는 상속(extends)을 통한 사용이고, 인터페이스는 구현(implements)을 통한 사용
2. 구성요소 차이 - 추상클래스는 일반 클래스와 동일하게 변수, 메소드의 모든 기능을 사용할 수 있지만, 인터페이스는 상수와 추상메소드만이 존재
4. 단일상속, 다중구현 - 추상클래스는 상속이므로 단일 상속만 지원하고, 인터페이스는 다중구현이 가능

ex

ex1. 음식점 1, 2, 3호점의 메뉴 가격을 각각 설정

1. HeadQuarterStore

  • interface
  • 각 메뉴들을 추상메소드로 선언
  • 스토어 이름
package com.lec.ex02_store;

public interface HeadQuarterStore {
	public abstract void kimchi();

	public abstract void bude();

	public abstract void bibim();

	public abstract void sunde();

	public abstract void gongibab();

	public String getStoreName();
}

2. Store1

  • 1호점: 김치찌개-4,500 부대찌개-5,000 비빔밥-6,000 순대국-안팔아 공기밥-1,000원
package com.lec.ex02_store;

public class Store1 implements HeadQuarterStore {
	private String storeName;
	public Store1(String storeName) {
		this.storeName = storeName;
	}
	@Override
	public void bude() {
		System.out.println("부대찌개 : 5,000원");
	}
	@Override
	public void sunde() {
		System.out.println("순대국 안 팔아");
	}
	@Override
	public void kimchi() {
		System.out.println("김치찌개 : 4,500원");
	}
	@Override
	public void bibim() {
		System.out.println("비빔밥 : 6,000원");
	}
	@Override
	public void gongibab() {
		System.out.println("공기밥 1,000원");
	}
	public String getStoreName() {
		return storeName;
	}
}

3. Store2

  • 2호점 : 김치찌개-5,000 부대찌개-5,000 비빔밥-5,000 순대국-5,000 공기밥-무료
package com.lec.ex02_store;

public class Store2 implements HeadQuarterStore {
	private String storeName;
	public Store2(String storeName) {
		this.storeName = storeName;
	}
	@Override
	public void bude() {
		System.out.println("부대찌개 : 5,000원");
	}
	@Override
	public void bibim() {
		System.out.println("비빔밥 : 5,000원");
	}
	@Override
	public void gongibab() {
		System.out.println("공기밥 : 무료");
	}
	@Override
	public void kimchi() {
		System.out.println("김치찌개 : 5,000원");
	}
	@Override
	public void sunde() {
		System.out.println("순대국 : 5,000원");
	}
	public String getStoreName() {
		return storeName;
	}

4. Store3

  • store3 : 김치찌개-6,000 부대찌개-7,000 비빔밥-7,000 얼큰순대국-6,000
package com.lec.ex02_store;

public class Store3 implements HeadQuarterStore{
	private String storeName;
	public Store3(String storeName) {
		this.storeName = storeName;
	}
	@Override
	public void kimchi() {System.out.println("김치찌개 : 6,000원");}
	@Override
	public void bude() {System.out.println("부대찌개 : 7,000원");}
	@Override
	public void bibim() {System.out.println("비빔밥 : 7,000원");}
	@Override
	public void sunde() {System.out.println("얼큰순대국 : 6,000원");}
	@Override
	public void gongibab() {System.out.println("공기밥 : 1,000원");}
	public String getStoreName() {
		return storeName;
	}

5. StoreMain

package com.lec.ex02_store;

public class StoreMain {
	public static void main(String[] args) {
		HeadQuarterStore[] stores = {
				new Store1("= = 주택가 1호점 = ="),  //이름 설정
				new Store2("= = 대학가 2호점 = ="),
				new Store3("= = 증권가 3호점 = =")};
//		for(int idx=0 ; idx<stores.length ; idx++) {
//			System.out.println(stores[idx].getStoreName());
//			stores[idx].kimchi();
//			stores[idx].bude();
//			stores[idx].bibim();
//			stores[idx].sunde();
//			stores[idx].gongibab();
//		}//일반 for
		for(HeadQuarterStore store : stores) {		//메뉴 가져와서 출력
			System.out.println(store.getStoreName());
			store.kimchi();
			store.bude();
			store.bibim();
			store.sunde();
			store.gongibab();
		}// 확장 for
	}// main
}

ex2. Speaker, Tv 볼륨 조절 프로그램

1. IVolume

  • 볼륨 올리기(1만큼, level만큼)
  • 볼륨 내리기(1만큼, level만큼)
  • 무음 모드
package com.lec.ex03_speakertv;

public interface IVolume {
	public void volumeUp();  //볼륨 레벨 1씩 up
	public void volumeUp(int level);   //볼륨 레벨을 level 씩 up
	public void volumeDown();  //볼륨 레벨 1씩 down
	public void volumeDown(int level);   //볼륨 레벨을 level 씩 down
	public default void setMute(boolean mute) { //디폴트 메소드
		if(mute) {
			System.out.println("무음");
		}else {
			System.out.println("무음해제");
		}
	}
	public static void changeBattery() {  //static 메소드
		System.out.println("건전지를 교환합니다");
	}
}

2. Speaker

  • IVolume을 implements한 클래스
  • Speaker의 최소, 최대 볼륨 설정
  • 초기 볼룜값 설정
  • 볼륨 올릴 시 출력할 메세지, 최소, 최대 볼륨일 시 출력할 메세지
package com.lec.ex03_speakertv;

public class Speaker implements IVolume {
	private int volumeLevel;
	private final int MAX_VOLUME = 50;
	private final int MIN_VOLUME = 0;

	public Speaker() {
		volumeLevel = 10;
	}

	@Override
	public void volumeUp() { // 볼륨을 1씩 증가
		// TODO Auto-generated method stub
		if (volumeLevel < MAX_VOLUME) {
			volumeLevel++;
			System.out.println("스피커 볼륨을 1만큼 올려 현재 볼륨은 " + volumeLevel);
		} else {
			System.out.println("스피커 볼륨이 최대입니다");
		}
	}

	@Override
	public void volumeUp(int level) {
		// TODO Auto-generated method stub
		if (volumeLevel + level < MAX_VOLUME) {
			volumeLevel += level;
			System.out.println("스피커 볼륨을 " + level + "만큼 올려 현재 볼륨은 " + volumeLevel);
		} else {
			int tempLevel = MAX_VOLUME - volumeLevel;
			volumeLevel = MAX_VOLUME;
			System.out.println("스피커 볼륨을 " + tempLevel + "만큼 올려 최대치입니다");
		}
	}

	@Override
	public void volumeDown() {
		// TODO Auto-generated method stub
		if (volumeLevel > MIN_VOLUME) {
			volumeLevel--;
			System.out.println("스피커 볼륨 1 내려 현재 " + volumeLevel);
		} else {
			System.out.println("스피커 볼륨이 최소입니다");
		}
	}

	@Override
	public void volumeDown(int level) {
		// TODO Auto-generated method stub
		if (volumeLevel - level > MIN_VOLUME) {
			volumeLevel -= level;
			System.out.println("스피커 볼륨 " + level + " 내려 현재 " + volumeLevel);
		} else {
			int tempLevel = volumeLevel - MIN_VOLUME;
			volumeLevel = MIN_VOLUME;
			System.out.println("스피커 볼륨이 최소입니다");
		}
	}
}

3. Tv

  • Speaker와 같이 볼륨값을 설정해줬다
package com.lec.ex03_speakertv;

public class Tv implements IVolume {
	private int volumeLevel;
	private final int MAX_VOLUME = 30;
	private final int MIN_VOLUME = 0;

	public Tv() {
		volumeLevel = 5;
	}

	@Override
	public void volumeUp() { // 볼륨을 1씩 증가
		// TODO Auto-generated method stub
		if (volumeLevel < MAX_VOLUME) {
			volumeLevel++;
			System.out.println("TV 볼륨을 1만큼 올려 현재 볼륨은 " + volumeLevel);
		} else {
			System.out.println("TV 볼륨이 최대입니다");
		}
	}

	@Override
	public void volumeUp(int level) {
		// TODO Auto-generated method stub
		if (volumeLevel + level < MAX_VOLUME) {
			volumeLevel += level;
			System.out.println("TV 볼륨을 " + level + "만큼 올려 현재 볼륨은 " + volumeLevel);
		} else {
			int tempLevel = MAX_VOLUME - volumeLevel;
			volumeLevel = MAX_VOLUME;
			System.out.println("TV 볼륨을 " + tempLevel + "만큼 올려 최대치입니다");
		}
	}

	@Override
	public void volumeDown() {
		// TODO Auto-generated method stub
		if (volumeLevel > MIN_VOLUME) {
			volumeLevel--;
			System.out.println("TV 볼륨 1 내려 현재 " + volumeLevel);
		} else {
			System.out.println("TV 볼륨이 최소입니다");
		}
	}

	@Override
	public void volumeDown(int level) {
		// TODO Auto-generated method stub
		if (volumeLevel - level > MIN_VOLUME) {
			volumeLevel -= level;
			System.out.println("TV 볼륨 " + level + " 내려 현재 " + volumeLevel);
		} else {
			int tempLevel = volumeLevel - MIN_VOLUME;
			volumeLevel = MIN_VOLUME;
			System.out.println("TV 볼륨이 최소입니다");
		}
	}
}

4. TestMain

  • array(배열)을 이용하여 스피커와 티비를 넣었다.
  • 확장 for문으로 데이터 뿌리기
  • 볼륨 조절해보기
package com.lec.ex03_speakertv;

public class TestMain {
	public static void main(String[] args) {
		IVolume speaker = new Speaker();
		IVolume tv = new Tv();
		IVolume[] devices = { speaker, tv };
		for (IVolume device : devices) {

			device.volumeDown();
			device.volumeDown(50);
			device.volumeUp();
			device.setMute(true);
			device.setMute(false);
		}
		speaker.setMute(true);
		IVolume.changeBattery();
	}
}
  • 결과
스피커 볼륨 1 내려 현재 9
스피커 볼륨이 최소입니다
스피커 볼륨을 1만큼 올려 현재 볼륨은 1
무음
무음해제
TV 볼륨 1 내려 현재 4
TV 볼륨이 최소입니다
TV 볼륨을 1만큼 올려 현재 볼륨은 1
무음
무음해제
무음
건전지를 교환합니다

ex3. 도서관 대출 반납 프로그램

1. ILendable(interface)

  • 책의 대출 가능여부(대출중, 대출가능), 대출 반납
package com.lec.quiz;

public interface ILendable {
	public byte STATE_BOOROWED = 1; //대출중
	public byte STATE_NORMAL = 0;   //대출가능
	public void checkOut(String borrower, String checkOutDate); //대출
	public void checkIn();		// 반납
	public void printState(); 	// "책번호 책이름(저자) 대출가능여부"  출력
}

2. BookInfo

  • 책번호, 책이름, 저자
package com.lec.quiz;

public class BookInfo {
	private String bookNo; // 책번호
	private String bookTitle; // 책이름
	private String writer; // 저자
	
	public BookInfo(String bookNo, String bookTitle, String writer) {
		super();
		this.bookNo = bookNo;
		this.bookTitle = bookTitle;
		this.writer = writer;
	}

	public String getBookNo() {
		return bookNo;
	}

	public void setBookNo(String bookNo) {
		this.bookNo = bookNo;
	}

	public String getBookTitle() {
		return bookTitle;
	}

	public void setBookTitle(String bookTitle) {
		this.bookTitle = bookTitle;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}
}

3. BookLib

  • extends BookInfo implements ILendable
    BookInfo를 extends, ILendable을 implements했다
  • 매개변수(책번호, 책이름, 저자) 메소드
  • 대출, 반납, 책 리스트 기능 만들기
package com.lec.quiz;

public class BookLib extends BookInfo implements ILendable {
	private String borrower; // 대출인
	private String checkOutDate; // 대출일
	private byte state; // 대충 상태 : 대출중(1), 대출가능(0)

	public BookLib(String bookNo, String bookTitle, String writer) {
		super(bookNo, bookTitle, writer);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void checkOut(String borrower, String checkOutDate) {
		if (state == STATE_BOOROWED) { // 대출중이면 메세지 뿌리고 끝
			System.out.println(getBookTitle() + "은 대출중입니다");
			return; // void 이기에 return 뒤에 값 입력 불가
		}
		this.borrower = borrower;
		this.checkOutDate = checkOutDate;
		state = STATE_BOOROWED; // 대출중 상태로 전환
		System.out.println(getBookTitle() + "도서가 대출 처리 되었습니다");
		System.out.println("대출인 : " + borrower + "\t대출일 : " + checkOutDate);
	}

	@Override
	public void checkIn() {
		if (state == STATE_NORMAL) {
			System.out.println(getBookTitle() + "도서는 반납완료된 책입니다. 확인하세요");
			return;
		}
		// state가 대출중(1)이라 반납 처리
		borrower = null;
		checkOutDate = null;
		state = STATE_NORMAL;
		System.out.println(getBookTitle() + "도서가 반납 완료되었습니다");

	}

	@Override
	public void printState() {
		String msg = getBookNo() + "\t" + getBookTitle() + "\t" + "(" + getWriter() + "著)-";
		msg += state == STATE_NORMAL ? "대출가능" : "대출 중";
		System.out.println(msg);
	}

	public byte getState() {
		return state;
	}
}

4. BookMain

  • array(배열)에 책 정보를 넣어주었다
  • 사용자가 원하는 데이터 입력 스캐너
  • switch case를 이용하여 case 1: 대출 case 2:반납 case 3:책조회
  • while(fn!=0) = 입력값이 0이 아닐때 까지 진행 (0은 종료)
package com.lec.quiz;

import java.util.Scanner;

public class BookMain {
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		BookLib[] books = {new BookLib("890ㅁ-01-11", "java", "홍길동"),
						new BookLib("890ㅁ-01-12", "oracle", "오길동"),
						new BookLib("890ㅁ-02-01", "mysql", "마길동"),
						new BookLib("890ㅁ-01-01", "jdbc", "제이디"),
						new BookLib("890ㅁ-01-01", "html", "이에이")};
		Scanner scanner = new Scanner(System.in);
		int fn;  // 기능번호 (1:대출/2:반납/3:책list/0:종료)
		int idx;  // 대출하거나 반납 시 조회된 책의 index
		String bTitle, borrower, checkOutDate;  // 사용자에게 받을 책 이름, 대출인, 대출일
		do {
			System.out.print("1:대출/ 2:반납/ 3:책list/ 0:종료");
			fn = scanner.nextInt();
			switch(fn) {
			case 1: // 대출 : 1.책이름입력 2.책조회 3.책상태확인 4.대출인입력 5.대출일입력 6.대출메소드 호출
				//1.책이름입력
				System.out.print("대출하고자 하는 책 이름은?");
				bTitle = scanner.next();  //white-space 앞까지의 스트링만 받음
				//2.책조회
				for(idx=0 ; idx<books.length ; idx++) {
					if(bTitle.equals(books[idx].getBookTitle())) {
						break;
					}
				}//for
				//idx번째 책으로 진행
				if(idx == books.length) {
					System.out.println("현재 보유하지 않은 도서입니다");
				} else { //books[idx] 도서를 대출
					//3.책상태확인
					if(books[idx].getState() == BookLib.STATE_BOOROWED) {
						System.out.println("현재 대출 중인 도서입니다");
					} else {
						//4.대출인입력
						System.out.println("대출인은 ?");
						borrower = scanner.next();
						//5.대출일입력
						System.out.println("대출일은 ?");
						checkOutDate = scanner.next();
						//6.대출메소드 호출
						books[idx].checkOut(borrower, checkOutDate);
					}//if 상태확인
				}//if 도서조회
				
				break;
			case 2: // 반납 : 1.책이름입력 2.책조회 3.반납메소드 호출
				System.out.print("반납하고자 하는 책 이름은?");
				bTitle = scanner.next();  //white-space 앞까지의 스트링만 받음
				//2.책조회
				for(idx=0 ; idx<books.length ; idx++) {
					if(bTitle.equals(books[idx].getBookTitle())) {
						break;
					}//for
				}
					if(idx== books.length) {
						System.out.println("해당 도서는 본 도서관의 책이 아닙니다");
					} else {
						//3.반납 메소드 호출
						books[idx].checkIn();
					}
					break;
			case 3: // 책list 출력 : for문을 이용하여 printState()메소드 호출
				for(BookLib book : books) {
					book.printState();
				}
			}//switch
		} while(fn!=0);
		System.out.println("종료");
	}
}
  • 결과
1:대출/ 2:반납/ 3:책list/ 0:종료1
대출하고자 하는 책 이름은?java
대출인은 ?
s
대출일은 ?
221212
java도서가 대출 처리 되었습니다     //java 도서 대출
대출인 : s	대출일 : 221212
1:대출/ 2:반납/ 3:책list/ 0:종료2
반납하고자 하는 책 이름은?java
java도서가 반납 완료되었습니다		//java 도서 반납
1:대출/ 2:반납/ 3:책list/ 0:종료3		//책list 확인
890ㅁ-01-11	java	(홍길동著)-대출가능
890ㅁ-01-12	oracle	(오길동著)-대출가능
890ㅁ-02-01	mysql	(마길동著)-대출가능
890ㅁ-01-01	jdbc	(제이디著)-대출가능
890ㅁ-01-01	html	(이에이著)-대출가능
1:대출/ 2:반납/ 3:책list/ 0:종료0		//종료
종료
profile
씨앗 개발자

0개의 댓글