본문 바로가기
프로그래밍 언어/java

[java] 인터페이스

by m2162003 2021. 3. 12.

인터페이스

구현 코드가 아예 없으며 클래스 대신 interface라고 붙이면 된다.

 

public interface Calc {
	double PI = 3.14;
	int ERROR = -99999999;

	public int add(int a, int b);

	public int sub(int a, int b);

	public int mul(int a, int b);

	public int div(int a, int b);
}

 

인터페이스의 역할

구현코드도 없는데 대체 왜 사용할까?

설계 단계에서 명세서 역할을 한다. 클라이언트 프로그램에 어떤 메서드를 제공하는지 알려주는 것이다.

사용자는 인풋, 아웃풋만 알면 될뿐...구현 과정은 알 필요가 없기 때문이다.

 

따라서 '한 객체가 어떤 인터페이스의 타입이다' = 그 객체가 인터페이스의 메서드를 구현했다 는 의미이다.

 

 

인터페이스를 통한 다형성 구현

인터페이스를 통해 다양한 객체를 구현한다.

예를 들어 자바의 JDBC (자바 프로그램과 DBMS를 연결해주는 라이브러리. sql 쿼리문 실행법 등이 구현되어 있다.)는 오라클, MYSQL, MSSQL등 각 DB 사에서 구현한다.

그러면 유저는 각 메서드가 어떤 역할을 하는지만 알고 가져다 쓴다.

 

 

인터페이스 구성 요소

- 상수: 선언된 모든 변수는 상수임

- 메서드: 모든 메서드는 추상 메서드(구현부 없음)

- default 메서드: 구현을 갖는 메서드. 구현하는 클래스에서 재정의가능. 주로 중복된 이름의 메서드에 적용한다.

- static 메서드: 인스턴스 생성과 상관없이 인터페이스 타입으로 호출하는 메서드

- private 메서드: 인터페이스 내에서 사용하기 위해 구현한 메서드. 구현하는 클래스에서 재정의 불가능

 

이 중에서 default, static 메서드는 java 8부터, private 메서드는 java 9부터 적용되는 메서드이다.

private 메서드는 두 가지가 존재하는데 같은 static 메서드에서 사용가능한 private static과 일반 메서드에서 사용가능한 private 메서드가 존재한다.

 

public interface Buy {
	void buy();

	default void order() {
		System.out.println("구매하세요");
	};
	// 중복 메서드에 대해 적용된다. 같은 이름의 메서드가 존재할 때에 구분하기 위해 미리 구현부가 존재한다.

	static int getSum(int[] arr) {
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum += arr[i];
		}
		return sum;
	}
}
public interface Sell {
	void sell();
	default void order() {
		System.out.println("판매하세요");
	};
}

 

이름이 중복된 order의 경우 Buy나 Sell 중 하나를 선택할 수 있다.

public class Customer implements Buy, Sell {

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

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

	@Override
	public void order() {
		Sell.super.order();
		//Buy.super.order();도 가능
	}

}

 

 

public class CustomerTest {
	public static void main(String[] args) {
		Customer customer = new Customer();

		customer.buy();
		customer.sell();
		customer.order();

		int[] arr = { 12, 3, 4, 5 };
		System.out.println(Buy.getSum(arr)); //static 메서드 사용 가능

		Buy buyer = new Customer();
		buyer.buy(); // only buy available
        	buyer.order();
	}
}

buyer의 경우 Customer이지만 Buy가 Sell을 상속하지 않기 때문에 sell 메서드는 사용 불가능하다.

대신 buyer.order은 인스턴스에서 구현된 메서드가 호출된다.

 

 

타입상속과 형변환

인터페이스를 구현한 클래스는 인터페이스 타입으로 변수를 선언하여 인스턴스를 생성할 수 있다.

인터페이스 상속은 타입 상속이라고도 불린다.

 

Calc calc = new CompleteCalc();

 

점선은 implements를 의미한다.

public abstract class Calculator implements Calc {
	@Override
	public int add(int a, int b) {
		return a + b;
	}

	@Override
	public int sub(int a, int b) {
		return a - b;
	}
}

Calculator는 Calc 인터페이스를 상속한다. abstract로 선언하여 전체를 다 구현하지 않고 일부만 구현했다.

 

 

 

public class CompleteCalculator extends Calculator {
	@Override
	public int mul(int a, int b) {
		return a * b;
	}

	@Override
	public int div(int a, int b) {
		if (b == 0) {
			return ERROR;
		}
		return a / b;
	}

	public void showInfo() {
		System.out.println("계산기입니다.");
	}
}

CompleteCalculator는 Calculator를 extends한다.

상위 클래스인 Calculator에서 구현하지 않은 나머지 메서드를 구현해야 한다.(안하면 에러남)

 

 

 

 

 

public class CalcTest {

	public static void main(String[] args) {
		CompleteCalculator cc = new CompleteCalculator();

		System.out.println(cc.add(1, 2));
		System.out.println(cc.sub(1, 2));
		System.out.println(cc.mul(1, 2));
		System.out.println(cc.div(1, 2));
		cc.showInfo();

		Calculator cal = new CompleteCalculator();
		System.out.println(cal.add(1, 2));
		System.out.println(cal.sub(1, 2));
		System.out.println(cal.mul(2, 0)); // 이미 정의된 인스턴스의 함수가 실행된다.
		System.out.println(cal.div(1, 0));
		// cal.showInfo(); 상위 클래스에 정의되지 않은 메서드는 사용 불가능

		Calc c = new CompleteCalculator();

	}
}

CompleteCalculator로 선언된 cal은 상위클래스인 Cal에 선언된 mul, div는 사용가능하다.

그러나 CompleteCalculator에만 선언된  showInfo()는 사용 불가능하다.

'프로그래밍 언어 > java' 카테고리의 다른 글

[java] Object 클래스  (0) 2021.03.18
[java] 인터페이스 다중 상속  (0) 2021.03.12
[java] final, 템플릿 메서드  (0) 2021.03.11
[java] 추상클래스  (0) 2021.03.11
[java] 업캐스팅, 타운캐스팅  (0) 2021.03.10

댓글