Java/모두의 자바

Chapter 08-44 인터페이스 사용하기

계란💕 2022. 2. 12. 21:58

08-44.1 인터페이스 

  - 앞에서 살펴 봤듯이 인터페이스는 객체를 선언하기 전에 이 객체가 가지고 있어야 할 기능을 모아 놓은 것이다.

  - 인터페이스는 반드시 해당 인퍼페이스를 구현하는 클래스가 있어야 사용할 수 있다. 

 

  (1) 앞 단원에서 만든 인터페이스 TV

<hide/>
package javaStudy;
public interface TV {
	public int MIN_VOLUME = 0;
	public int MAX_VOLUME = 0;
	public void turnOn();
	public void turnOff();
	public void changeVolume(int volume);
	public void changeChannel(int channel);
}

 

  (2) TV인터페이스를 구현하는 LedTV 클래스 만든다.

<hide/>
package javaStudy;
public class LedTV implements TV {

	@Override
	public void turnOn() {
		// TODO Auto-generated method stub

	}

	@Override
	public void turnOff() {
		// TODO Auto-generated method stub

	}

	@Override
	public void changeVolume(int volume) {
		// TODO Auto-generated method stub

	}

	@Override
	public void changeChannel(int channel) {
		// TODO Auto-generated method stub

	}

}

  - public class LedTV implements TV : LedTV가 TV인터페이스를 구현하겠다는 의미이다.

  - LedTV는 TV가 가진 메서드를 반드시 구현해야 한다. 

 

  (3) 원하는 메서드를 구현한다.

<hide/>
package javaStudy;
public class LedTV implements TV {

	@Override
	public void turnOn() {
		// TODO Auto-generated method stub
		System.out.println("켜다");
	}

	@Override
	public void turnOff() {
		// TODO Auto-generated method stub
		System.out.println("끄다");
	}

	@Override
	public void changeVolume(int volume) {
		// TODO Auto-generated method stub
		System.out.println("볼륨을 조절하다");
	}

	@Override
	public void changeChannel(int channel) {
		// TODO Auto-generated method stub
		System.out.println("채널을 변경하다");
	}

}

 

  (4) 테스트하기 위해 LedExam클래스를 만든다.

<hide/>
package javaStudy;
public class LedExam {
	public static void main(String[] args) {
		TV tv = new LedTV();
		tv.turnOn();
		tv.changeVolume(8);
		tv.changeChannel(39);
		tv.turnOff();
	}
}

  Note) 실행 결과

  - TV라는 타입으로 참조변수를 만든다.

  - 인터페이스도 타입이 될 수 있다.

  - TV인터페이스 타입으로 선언한 변수로 LedTV 인스턴스를 참조해 사용할 수 있다.

  - 인터페이스와 상속과 공통점

    -> 참조 변수의 타입으로 인터페이스를 사용할 수 있다.

    -> 인터페이스가 가진 메서드만 사용할 수 있다.

  - 만약 LedTV가 TV인터페이스에 없는 기능을 확장해 사용하고 싶다면?

    -> 클래스 형변환을 이용한다. 

  Ex)

TV tv = new LcdTV()

  - 같은 인터페이스를 구현한다는 것은 클래스 사용법이 똑같다는 뜻이다. 

  - 이는 인터페이스를 사용하는 중요한 이유이다. 

  - 클래스는 1개 이상의 인터페이스를 구현할 수 있다. 

 

 

08-44.2 왜 인터페이스를 만들까?

 

  - 예제처럼 TV는 여러가지 필수 기능이 있다. 모델 마다 기능이 조금씩 다르고 설정도 다르다.

  - 1번 모델은 볼륨을 한 번에 1씩 올리고 내리게 설정하고 2번 모델은 볼륨을 한 번에  10씩 조절된다고 하자.

  - 볼륨조절 기능을 공통적인 필수 기능이다.

  - 인터페이스스 사용하면 클래스 하나로 저 기능을 바로 구현할 수 있다. 

  - 호출하는 클래스만 변경하면 된다. 

  - 인터페이스를 사용하지 않으면 중복기능들을 각 모델(클래스)마다 구현해야 하기 해야해서 번거롭다.

 

 

08-44.3 인터페이스 사용하기 실습

  Ex 1) Meter인터페이스는 start와 stop이라는 추상메서드가 있다. stop메서드는 택시가 달린 거리에 해당하는 값을 매개변수로 받아 요금을 int형으로 반환하는 메서드이다. Meter인터페이스를 구현하는 택시클래스를 완성하라. 

 요금 = distance * 2

<hide/>
package javaStudy;
public class Taxi implements Meter {
//정답	public void start() {
//	}
//	public int stop(int distance) {
//		return 2 * distance;
//	}
}
<hide/>
package javaStudy;
public interface Meter {
	public abstract void start();
	public abstract int stop(int distance);	
}
<hide/>
package javaStudy;
public class MeterExam {
	public static void main(String[] args) {
		Taxi taxi = new Taxi();
		boolean a = Meter.class.isInstance(taxi);
		if( a!= true ){
			System.out.println("Taxi클래스는 Meter 인터페이스를 구현해야 합니다.");
		}
		else if( taxi.stop(200) != 400 ){
			System.out.println("stop(200)의 값은 400이어야 합니다.");
		}
		else {
			System.out.println("정답입니다.");
		}
	}
}

  Note) 실행 결과: 정답입니다.

  - 인터페이스를 구현하기 위한 키워드는 "implements"이다.

  - stop메서드의 요구 사항인 2 * distance를 리터한도록 한다.

 

 

08-44.4 인터페이스 사용하기 실습  

  Ex 2) 다음 코드를 실행하라. TaxiExam에서 "cannot assign a value to final variable BASE_FARE"라는 에러가 난다.

 Meter인터페이스에서 정의한 BASE_FARE라는 변수의 값을 변경하려고 하기 때문이다. 인터페이스에서 정의한 변수를 모두 상수이기 때문에 변경할 수 없다. BASE_FARE의 값을 변경하고 싶으면 BASE_FARE정의한 부분은 Meter인터페이스가 아닌 Taxi클래스로 옮기면 된다. 

 

변경 전)

<hide/>
package javaStudy;
public interface Meter {
	public int BASE_FARE = 3000;
	public abstract void start();
	public abstract int stop(int distance);	
}
<hide/>
package javaStudy;
public class Taxi implements Meter {
	public void start() {
		System.out.println("운행을 시작합니다.");
	}
	public int stop(int distance) {
		int fare = BASE_FARE + distance * 2;
		System.out.println("운행을 종료합니다. 요금은 " + fare + "원입니다.");
		return fare;
	}
}
<hide/>
package javaStudy;
public class TaxiExam {
	public static void main(String[] args) {
		Taxi taxi = new Taxi();
		System.out.println("기본요금 변경 전!!");
		taxi.stop(20);
		taxi.BASE_FARE = 2500;
		System.out.println("기본요금 변경 후!!");
		taxi.stop(20);	
	}
}

 

변경 후)

<hide/>
package javaStudy;
public interface Meter {

	public abstract void start();
	public abstract int stop(int distance);	
}
<hide/>
package javaStudy;
public class Taxi implements Meter {
	public void start() {
		System.out.println("운행을 시작합니다.");
	}
	public int BASE_FARE = 3000;
	public int stop(int distance) {
		int fare = BASE_FARE + distance * 2;
		System.out.println("운행을 종료합니다. 요금은 " + fare + "원입니다.");
		return fare;
	}
}

  Note) 실행결과

  - 인터페이스에 선언한 변수는 무조건 상수로 처리 된다.

  - 이렇게 선언한 변수는 실행 중에 값을 바꿀 수 없다. 

  - 그러므로 기본요금(BASE_FARE)을 인터페이스에 선언하면 안 된다.