티스토리 뷰

개인공부/JAVA

JAVA - INTERFACE

날따라해봐요요롷게 2021. 3. 12. 00:06

출처 : DO IT! 자바프로그래밍 (저 : 박은종)

INTERFACE 인터페이스

  • 인터페이스란
  • 인터페이스와 다형성
  • 인터페이스 요소 살펴보기
  • 인터페이스 활용하기
  • 인터페이스란

인터페이스는 구현 코드가 없다. 추상 메서드와 상수로만 이루어져 있다.

이러한 인터페이스는 클래스 혹은 프로그램이 제공하는 기능을 명시적으로 선언하는 역할을 한다.

 

- implements 

 : 인터페이스에서는 인터페이스에 선언한 기능을 클래스가 구현한다는 의미로 implements 예약어를 사용

 

구현하는 클래스에서는 인터페이스에 선언된 추상메서드를 구현한다.

 

package Interface;

public interface Calc {
	double PI = 3.14;
	int ERROR = -99999999;
	
	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 Interface;

public class Calculator implements Calc {

	@Override
	public int add(int num1, int num2) {
		// TODO Auto-generated method stub
		return num1 + num2;
	}

	@Override
	public int substract(int num1, int num2) {
		// TODO Auto-generated method stub
		return num1 - num2;
	}


}

==========

package Interface;

public abstract class CompleteCalc extends Calculator{
	@Override
	public int times(int num1, int num2) {
		// TODO Auto-generated method stub
		return num1 * num2;
	}

	@Override
	public int divide(int num1, int num2) {
		if(num2!=0) {
			return num1/num2;
		}
		return Calc.ERROR;
	}
	public void showInfo() {
		System.out.println("Clac 인터페이스를 구현하였습니다.");
	}
}
============

package Interface;

public class CalculatorTest {

	public static void main(String[] args) {
		int num1 = 10;
		int num2 = 5;
		
		CompleteCalc 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.showInfo();
	}

}

ㄴ위의 코드를 살펴보면 CompleteClac 클래스만이 인스턴스를 생성할 수 있다. -> Calculator 클래스는 추상클래스이기에 인스턴스를 생성할 수 없다.

Calc <- Calculator <- CompleteCalc 형태로 상위 클래스를 이룬다.

그렇다면 하위클래스의 형 변환은 어떻게 이루어 지는지 살펴보자

-> 상속관계에서 하위클래스는 상위 클래스 자료형으로 묵시적 형 변환이 가능하다. 인터페이스도 같다.

CompleteCalc 클래스는 상위 클래스인 Calculator 형이면서 Calc 형이기도 하다.

Calc calc = new CompleteCalc();

Calc newCalc = calc; -> Clac 형 변수인 newCalc에 calc변수를 대입한다.

newCalc가 사용할 수 있는 메서드를 살펴보자. showInfo 메서드를 사용할 수 없다.

Calc형으로 선언한 변수에서 사용할 수 있는 메서드는 Calc 인터페이스에 선언한 메서드뿐이다.

정리!!

=> 인터페이스를 구현한 클래스가 있을 때 그 클래스는 해당 인터페이스형으로 묵시적 형 변환이 이루어지며, 형 변환되었을 때 사용할 수 있는 메서드는 인터페이스에서 선언한 메서드 뿐이다.

 

  • 인터페이스와 다형성

인터페이스를 사용하는 이유는 무엇일까?

=> 인터페이스는 말 그대로 껍데기일 뿐이다. 하지만 인터페이스는 메서드를 통해서 앞으로 전개될 코드를 추측할 수 있도록 해주는 역할을 한다.

 

인터페이스의 다형성 

 : 인터페이스를 사용하면 다형성을 구현하여 확장성 있는 프로그램을 만들 수 있다.

클라이언트 프로그램을 많이 수정하지 않고 기능을 추가하거나 다른 기능을 사용할 수 있다.

 

package InterfaceEX;

public interface Scheduler {
	public void getNextCall();
	public void sendCallToAgent();
}


==

package InterfaceEX;

public class RoundRobin implements Scheduler {

	@Override
	public void getNextCall() {
		System.out.println("상담 전화를 순서대로 대기열에서 가져옵니다.");
		
	}

	@Override
	public void sendCallToAgent() {
		System.out.println("다음 순서 상담원에게 배분합니다.");
		
	}
	
}
=====
package InterfaceEX;

public class PriorityAllocation implements Scheduler{

	@Override
	public void getNextCall() {
		System.out.println("고객 등급이 높은 고객의 전화를 먼저 가져옵니다.");
		
	}

	@Override
	public void sendCallToAgent() {
		System.out.println("업무 skill 값이 높은 상담원에게 우선적으로 배분합니다.");
		
	}

}
=====
package InterfaceEX;

public class LeastJob implements Scheduler{

	@Override
	public void getNextCall() {
		System.out.println("상담 전화를 순서대로 대기열에서 가져옵니다.");
		
	}

	@Override
	public void sendCallToAgent() {
		System.out.println("현재 상담 업무가 업거나 대기가 가장 적은 상담원에게 할당합니다.");
		
	}
	
}
=====
package InterfaceEX;
import java.io.IOException;

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

}

 

ㄴ 위의 코드를 살펴보자

 : 인터페이스를 생성하고 세 개의 클래스는 해당 인터페이스를 implements 한다.

test클래스를 살펴보면 입력값에 따라 클래스로 생성한 인스턴스는 scheduler 형 변수에 대입할 수 있게된다.

그리고 어떤 인스턴스가 생성이 된거와 상관없이 인터페이스에서 제공하는 메서드를 사용하면 된다.

이것이 인터페이스를 활용해 다형성을 구현한 것이다.

 

  • 인터페이스 요소 살펴보기

인터페이스에서는 메서드를 구현하지 않는다고 하였다. 하지만 java 8 부터는 인터페이스에서 메서드를 구현하여 활용할 수 있도록 하였다. 그 방법이 2가지가 있는데 알아보자.

 

## 디폴트 메서드

 : 기본으로 제공되는 메서드이다. 인터페이스에서 구현하여 인터페이스를 구현한 클래스에서는 디폴트 메서드를 사용할 수 있다. 디폴트 메서드를 선언할 때는 default 예약어를 사용하면 된다.

 -> 디폴트 메서드 재정의

     : 구현되어 있는 디폴트 메서드가 새로 생성한 클래스에서 원하는 기능이 아니라면 하위클래스에서 재정의 할 수 있다.

 

## 정적 메서드

 : static 예약어를 사용하여 선언하며 클래스 생성과 무관하게 사용할 수 있다.

**특징! 정적 메서드를 사용할 때는 참조변수 없이 인터페이스 이름으로 직접참조가 가능하다!!

 

  • 인터페이스 활용하기

## 한 클래스가 여러 인터페이스 구현

 

package InterfaceEX1;

public interface Buy {
	void buy();
	default void order() {
		System.out.println("구매 주문");
	}
}

====
package InterfaceEX1;

public interface Sell {
	void sell();
	default void order() {
		System.out.println("판매 주문");
	}
}
===

package InterfaceEX1;

public class Customer implements Buy, Sell{

	@Override
	public void sell() {
		System.out.println("판매");
		
	}

	@Override
	public void buy() {
		System.out.println("구매");
		
	}

	@Override
	public void order() {
		System.out.println("customer 클래스에서 구현된 메서드 등장");
	}
	
}

======
package InterfaceEX1;

public class CustomerTest {

	public static void main(String[] args) {
		Customer customer = new Customer();
		
		Buy buyer = customer;	//중요!! Customer 클래스형인 customer를 Buy 인터페이스형인 buyer에 대입하여 형 변환
		buyer.buy();
		buyer.order(); //
		
		Sell seller = customer;
		seller.sell();
		seller.order(); //
		
		if(seller instanceof Customer) {
			Customer customer2 = (Customer)seller;
			customer2.buy();
			customer2.sell();
			customer2.order(); //디폴트 메소드는 인터페이스를 implements 한 클래스에서 재정의한 메소드 등장( vmc 자바가상머신이 메소드를 참조하는 방법 )
		}
	}

}

 ㄴ위의 코드를 살펴보자

Customer 클래스는 Buy, Sell 인터페이스를 implements 하고 있다.

인터페이스는 구현 코드나 멤버변수를 갖고 있지 않기에 여러개를 동시에 구현할 수 있다.

두 인스턴스에 같은 order 디폴트 메서드가 생성되어 있지만, 두 인터페이스를 implements 한 Customer 클래스에서 재정의된 order 메서드가 사용된다. 

 

## 인터페이스 구현과 클래스 상속 함께 쓰기

package InterfaceEX3;

public interface Queue {
	void enQueue(String title);
	String deQueue();
	int getSize();
}

======
package InterfaceEX3;

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 InterfaceEX3;

public class BookShelf extends Shelf implements Queue {

	@Override
	public void enQueue(String title) {
		shelf.add(title);
		
	}

	@Override
	public String deQueue() {
		// TODO Auto-generated method stub
		return shelf.remove(0);
	}

	@Override
	public int getSize() {
		// TODO Auto-generated method stub
		return getCount();
	}

}
========
package InterfaceEX3;

public class BookShelfTest {

	public static void main(String[] args) {
		Queue shelfQueue = new BookShelf();
		
		shelfQueue.enQueue("일");
		shelfQueue.enQueue("이");
		shelfQueue.enQueue("삼");
		
		System.out.println(shelfQueue.deQueue());
		System.out.println(shelfQueue.deQueue());
		System.out.println(shelfQueue.deQueue());

	}

}

인터페이스 Queue와 Shelf 클래스를 생성 -> BookShelf 클래스는 각각을 상속하고 implements 한다.

 

출처 : DO IT! 자바프로그래밍 (저 : 박은종)

'개인공부 > JAVA' 카테고리의 다른 글

JAVA - Inner Class, Lambda , Stream  (0) 2021.03.21
JAVA - CLASS  (0) 2021.03.16
JAVA - Abstract  (0) 2021.03.10
JAVA - Class 와 Object - 2  (0) 2021.03.08
JAVA - Class와 Object (1)  (0) 2021.03.02
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함