본문 바로가기
학습/JAVA

8. 인터페이스

by Elfen Lied 2022. 10. 17.
반응형

- 인터페이스란?

  • 클라이언트 객체와 사용 객체가 서로 통신하는 수단
  • 클라이언트 객체는 인터페이스의 메소드만 알고 있으면 된다.
    • • 즉 클라이언트 객체는 사용 객체의 내부 구조를 알 필요가 없다.
    • • 클라이언트 객체가 인터페이스의 메소드를 호출하면 사용 객체의 메소드를 호출한다.

 

  • 인터페이스를 두는 이유
    • 개방폐쇄원칙 실현(OCP, open close principle )
    • 수정에는 폐쇄적이고 확장에는 개방적이다.
    • 새로운 요구사항과 변경에 유연하게 대처할 수 있다.
    • 객체 간의 느슨한 결합(Loose Coupling)을 위해 사용한다.
    • 클라이언트 객체의 수정 없이 사용 객체를 변경할 수 있다.

 

 

- 인터페이스의 선언

- 상수필드 선언

  • 상수 필드만 선언할 수 있다.
  • 인터페이스에 선언된 필드는 모두 public static final의 특성을 갖는다.
  • 따라서 public static final 생략할 수 있다.

 

- 추상 메소드 선언

  • 인터페이스에는 추상 메소드를 선언할 수 있다.
  • 추상 메소드가 아닌 인스턴스 메소드를 정의할 수 없다.
  • 인터페이스에 선언된 추상 메소드는 모두 public abstrac의 특성을 갖는다.
  • 따라서 public abstract를 생략할 수 있다.

 

- 디폴드 메소드와 정적 메소드

  • 자바8에서 추가된 멤버
  • public의 특성을 갖는다. public을 생략할 수 있다.
  • 디폴트 메소드는 default 키워드가 반환타입 앞에 붙는다.
  • 디폴트 메소드는 인스턴스 메소드처럼 중괄호 블록을 가져야 한다.
public interface RemoteControl {
	// 인터페이스 필드
	// 상수만 선언가능. 인스턴스 필드 선언 불가. 스태틱 필드 선언 불가
	// "public static final" 생략 가능
	// 생략해도 public static final 간주함
	
	static int MAX_VOLUME = 10;
	static int MIN_VOLUME = 0;

	//  추상 메소드는 모두 "public abstract"의 특성을 가지므로 생략가능.
	// 추상메소드(정적메소드X, 인스턴스 메소드)
    // 실체클래스(구현클래스)에서 반드시 오버라이딩 해야함
//	public abstract void turnOn(); 
//	public abstract void turnOff(); 
//	public abstract void setVolume(int volume); 
	void turnOn(); 
	void turnOff();
	void setVolume(int volume);
	
	// static 메소드(추상메소드X) - 오버라이딩 불가능
	// 접근제한자 : public
	static void changeBattery() {
		System.out.println("건전지 교체");
	}
	
	// default 메소드(인스턴스 메소드 - 오버라이드 가능)
	// 선택적 오버라이딩
	default void setMute(boolean mute) {
		if(mute) {
			System.out.println("무음처리");
		} else {
			System.out.println("무음해제");
		}
	}
}

======================================================================

// Television이 RemoteControl인터페이스 구현
// 추상메소드를 모두 구현(오버라이딩)하여야 한다.
// 디폴트 메소드는 선택적으로 오버라이딩 할 수 있다.
public class Television implements RemoteControl{
	
	private int volume;

	@Override
	public void turnOn() {
		System.out.println("TV 켬");
	}

	@Override
	public void turnOff() {
		System.out.println("TV 끔");
	}

	@Override
	public void setVolume(int volume) {
		if(volume > RemoteControl.MAX_VOLUME) {
			this.volume = MAX_VOLUME;
		} else if(volume < MIN_VOLUME) {
			this.volume = MIN_VOLUME;
		} else {
			this.volume = volume;
		}
		System.out.println("현재 TV 볼륨 : " + this.volume);
	}
}

======================================================================

// 메인
public class TvMain {
	public static void main(String[] args) {
		// Television tv = new Television();
		// 인터페이스(RemoteControl) 타입은 
		// 구현객체(Television)의 상위타입이 될 수 있다.
		RemoteControl tv = new Television();
		tv.turnOn();
		tv.turnOff();
		tv.setVolume(100);
		tv.setVolume(-10);
		tv.setMute(false); // 디폴트 메소드
	}
}

 

 

- 인터페이스를 구현한 추상클래스

  • 인터페이스에서 선언한 메소드를 모두 구현해야 실체 클래스가 된다.
  • 인터페이스에 선언된 메소드 중 단 하나라도 구현하지 않는다면
  • 실체클래스가 아닌 추상클래스가 된다.
public abstract class Dummy implements RemoteControl{
	@Override
	public void turnOn() {
		System.out.println("전원 켬");
	}

	@Override
	public void turnOff() {
		System.out.println("전원 끔");
	}

//	@Override
//	public void setVolume(int volume) {
//		
//	}
}

==========================================================

// Dummy를 상속

public class DummyB extends Dummy{

	private int volume;
	
	@Override
	public void setVolume(int volume) {
		this.volume = volume;
	}
}

메소드중 setVolume을 만들지 않을경우 Class 앞에 abstract를 붙여 추상클래스로 해준다.

 

 

- 다중 인터페이스 구현 클래스

  • 상속과 달리 다수의 인터페이스를 구현할 수 있다
  • 실체클래스가 다수의 인터페이스를 구현하는 경우 모든 인터페이스의의 추상 메소드를 오버라이딩 해야한다.
  • 어느 하나라도 오버라이딩 하지 않을 경우 구현클래스는 추상클래스가 된다.

public abstract class Building implements Liftable, Repareable, Generatable, Upgradable{
	
}

class DummyA{}
class DummyB{}

interface Liftable{}
interface Repareable{}
interface Generatable{}
interface Upgradable{}

 

 

- 익명의 구현 객체

  • 명시적인 구현 클래스 작성 생략하고 바로 구현 객체를 얻는 방법
    • 이름 없는 구현 클래스 선언과 동시에 객체 생성
    • 인터페이스의 추상 메소드를 모두 재정의 해야 한다.
    • 추가적으로 필드와 메소드 선언 가능하나 익명 객체 안에서만 사용 가능
    • 인터페이스 변수로 접근 불가
  • 익명 구현 객체의 활용
    • UI 프로그래밍에서 이벤트처리
    • 스프링 JDBC 인터페이스
    • 임시 작업스레드 생성
    • 람다식

 

 

- 인터페이스 사용

- 디폴트 메소드 사용

  • 인터페이스만으로는 사용 불가
    • • 구현 객체가 인터페이스에 대입되어야 호출할 수 있는 인스턴스 메소드
  • 모든 구현 객체가 가지고 있는 기본 메소드로 사용
    • 필요에 따라 구현 클래스가 디폴트 메소드 재정의해 사용

 

- 정적 메소드 사용

▪ 인터페이스로 바로 호출 가능

반응형

댓글