본문 바로가기

BackEnd/Java

[java] 인터페이스

728x90
반응형

1. 인터페이스

   ▷ 두 객체를 연결하는 역할입니다.

   ▷ 다형성 구현에 주된 기술입니다.

 

◎ 인터페이스 선언

   ▷ 인터페이스 선언은 class 키워드 대신 interface 키워드를 사용합니다.

   ▷ 접근 제한자로는 클래스와 마찬가지로 같은 패키지 내에서만 사용 가능한 default,

      패키지와 상관없이 사용하는 public을 붙일 수 있습니다.

 

◎ 구현 클래스 선언

   ▷ 인터페이스에 정의된 추상 메소드에 대한 실행 내용이 구현됩니다.

   ▷ implements 키워드는 해당 클래스가 인터페이스를 통해 사용할 수 있다는 표시이며, 인터페이스의 추상 메소드를 재정의한 메소드가 있다는 뜻입니다.

 

◎ 변수 선언과 구현 객체 타입

   ▷ 인터페이스는 참조 타입에 속하므로 인터페이스 변수에는 객체를 참조하고 있지 않다는 뜻으로 null을 대입할 수 있습니다.

      ex) RemoteControl rc = null;

   ▷ 인터페이스를 통해 구현 객체를 사용하려면, 인터페이스 변수에 구현 객체의 번지를 대입해야 합니다.

 

1. RemoteControl 인터페이스
public interface RemoteControl {
	public void turnOn();
}​


2. Audio 클래스
public class Audio implements RemoteControl {
	@Override
	public void turnOn() {
		System.out.println("Audio를 켭니다.");
	}
}​


3. Television 클래스
public class Television implements RemoteControl {
	@Override
	public void turnOn() {
		System.out.println("TV를 켭니다.");
	}
}​


4. RemoteControlExample 메인 클래스
public class RemoteControlExample {
	public static void main(String[] args) {
		RemoteControl rc;        // 통합 리모컨
		rc = new Television();   // TV 버튼
		rc.turnOn();
		
		rc = new Audio();        // Audio 버튼
		rc.turnOn();
		
		Television tv = new Television();
		tv.turnOn();
		
		Audio au = new Audio();
		au.turnOn();
	}	
}​

 

 

2. 상수 필드

   ▷ 인터페이스는 public static final 특성을 갖는 불변의 상수 필드를 멤버로 가질 수 있습니다.

   ▷ 인터페이스에 선언된 필드는 모두 public static final 특성을 갖기 때문에 public static final을 생략해도 자동으로 컴파일 과정에서 붙습니다.

   ▷ 상수명은 대문자로 작성하되, 서로 다른 단어로 구성되어 있을 경우에는 언더바(_)로 연결됩니다.

 

1. RemoteControl 인터페이스 
public interface RemoteControl {
	int MAX_VOLUME = 10;
	int MIN_VOLUME = 0;
}​



2. RemoteControlExample 메인 클래스
public class RemoteControlExample {
	public static void main(String[] args) {
		System.out.println("리모콘 최대 볼륨: " + RemoteControl.MAX_VOLUME);
		System.out.println("리모콘 최저 볼륨: " + RemoteControl.MIN_VOLUME);
	}	
}​

 

 

3. 추상 메소드

   ▷ 리턴 타입, 메소드명, 매개변수만 기술되고 중괄호{ }를 붙이지 않는 메소드입니다.

   ▷ public abstract를 생략하더라도 컴파일 과정에서 자동으로 붙습니다.

   ▷ 추상 메소드는 객체 A가 인터페이스를 통해 어떻게 메소드를 호출할 수 있는지 방법을 알려주는 역할입니다.

 

1. RemoteControl 인터페이스
public interface RemoteControl {
	int MAX_VOLUME = 10;
	int MIN_VOLUME = 0;
	
	void turnOn();
	void turnOff();
	void setVolume(int volume);
}​


2. Television 클래스

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 = RemoteControl.MAX_VOLUME;
		} else if(volume < RemoteControl.MIN_VOLUME) {
			this.volume = RemoteControl.MIN_VOLUME;
		} else {
			this.volume = volume;
		}
		System.out.println("현재 TV 볼륨: " + this.volume);
	}	
}


setVolume 메소드에서 this.volume을 통일해서 사용해야 class의 필드 값을 가져올 수 있습니다.
만약 하나가 volume이라고만 사용했으면 조건문이 제대로 실행되지 않을 수 있습니다.


3. Audio 클래스

public class Audio implements RemoteControl {
	private int volume;
	
	@Override
	public void turnOn() {
		System.out.println("Audio를 켭니다.");
	}
	
	@Override
	public void turnOff() {
		System.out.println("Audio를 끕니다.");
	}
	
	@Override
	public void setVolume(int volume) {
		if(volume > RemoteControl.MAX_VOLUME) {
			this.volume = RemoteControl.MAX_VOLUME;
		} else if(volume < RemoteControl.MIN_VOLUME) {
			this.volume = RemoteControl.MIN_VOLUME;
		} else {
			this.volume = volume;
		}
		System.out.println("현재 Audio 볼륨: " + this.volume);
	}	
}



4. RemoteControlExample 메인 클래스

public class RemoteControlExample {
	public static void main(String[] args) {
		RemoteControl rc;
		
		rc = new Television();
		rc.turnOn();
		rc.setVolume(-1);
		rc.turnOff();
		
		rc = new Audio();
		rc.turnOn();
		rc.setVolume(5);
		rc.turnOff();		
	}	
}

// 출력 : 
// TV를 켭니다.
// 현재 TV 볼륨: 0
// TV를 끕니다.
// Audio를 켭니다.
// 현재 Audio 볼륨: 5
// Audio를 끕니다.​

 

4. 디폴트 메소드

   ▷ 인터페이스에는 완전한 실행 코드를 가진 디폴트 메소드를 선언할 수 있음

   ▷ 추상 메소드는 실행부(중괄호{ })가 없지만 디폴트 메소드는 실행부가 있습니다. default 키워드가 리턴 타입 앞에 붙습니다.

   ▷ 디폴트 메소드의 실행부에는 상수 필드를 읽거나 추상 메소드를 호출하는 코드를 작성할 수 있습니다.

 

1. RemoteControl 인터페이스
public interface RemoteControl {
	int MAX_VOLUME = 10;
	int MIN_VOLUME = 0;
	
	void turnOn();
	void turnOff();
	void setVolume(int volume);
	
	default void setMute(boolean mute) {
		if(mute) {
			System.out.println("무음 처리합니다.");
			setVolume(MIN_VOLUME);
		} else {
			System.out.println("무음 해제합니다.");
		}
	}
}​


2. Television 클래스
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 = RemoteControl.MAX_VOLUME;
		} else if(volume < RemoteControl.MIN_VOLUME) {
			this.volume = RemoteControl.MIN_VOLUME;
		} else {
			this.volume = volume;
		}
		System.out.println("현재 TV 볼륨: " + this.volume);
	}	
}​


3. Audio 클래스
public class Audio implements RemoteControl {
	private int volume;
	
	@Override
	public void turnOn() {
		System.out.println("Audio를 켭니다.");
	}
	
	@Override
	public void turnOff() {
		System.out.println("Audio를 끕니다.");
	}
	
	@Override
	public void setVolume(int volume) {
		if(volume > RemoteControl.MAX_VOLUME) {
			this.volume = RemoteControl.MAX_VOLUME;
		} else if(volume < RemoteControl.MIN_VOLUME) {
			this.volume = RemoteControl.MIN_VOLUME;
		} else {
			this.volume = volume;
		}
		System.out.println("현재 Audio 볼륨: " + this.volume);
	}	
	
	private int memoryVolume;
	
	@Override
	public void setMute(boolean mute) {
		if(mute) {
			this.memoryVolume = this.volume;
			System.out.println("무음 처리합니다.");
			setVolume(RemoteControl.MIN_VOLUME);
		} else {
			System.out.println("무음 해제합니다.");
			setVolume(this.memoryVolume);
		}
	}
}​


4. RemoteControlExample 메인 클래스
public class RemoteControlExample {
	public static void main(String[] args) {
		RemoteControl rc;
		
		rc = new Television();
		rc.turnOn();
		rc.setVolume(5);
		rc.setMute(true);
		rc.setMute(false);
		rc.turnOff();
		
		System.out.println();
		
		rc = new Audio();
		rc.turnOn();
		rc.setVolume(5);
		rc.setMute(true);
		rc.setMute(false);
		rc.turnOff();		
	}	
}​

 

 

5. 정적 메소드

   ▷ 구현 객체가 없어도 인터페이스만으로 호출할 수 있습니다.

   ▷ 선언시 public을 생략하더라도 자동으로 컴파일 과정에서 붙습니다.

      ex) [public | private] static 리턴타입 메소드명(매개변수, ...) { ... }

   ▷ 정적 실행부를 작성할 때 상수 필드를 제외한 추상 메소드, 디폴트 메소드, private 메소드 등을 호출할 수 없습니다.

 

1. RemoteControl 인터페이스
public interface RemoteControl {
	int MAX_VOLUME = 10;
	int MIN_VOLUME = 0;
	
	void turnOn();
	void turnOff();
	void setVolume(int volume);
	
	// 정적 메소드
	static void changeBattery() {
		System.out.println("리모콘 건전지를 교환합니다.");
	}
}​


2. RemoteControlExample 메인 클래스

public class RemoteControlExample {
	public static void main(String[] args) {
    
		// 정적 메소드 호출
		RemoteControl.changeBattery();
	}	
}

//	출력 : 
//	리모콘 건전지를 교환합니다.


default 코드에서 위의 코드만 추가시키면 됩니다.
정적 메소드를 사용하면 class명.메소드를 이용해서 바로 출력이 가능합니다.

 

 

6. private 메소드

   ▷ 인터페이스의 상수 필드, 추상 메소드, 디폴트 메소드, 정적 메소드는 모두 public 접근 제한을 가집니다.

      ▶ public을 생략하더라도 항상 외부에서 접근이 가능합니다.

   ▷ 인터페이스에 외부에서 접근할 수 없는 private 메소드 선언도 가능합니다.

   ▷ private 메소드는 디폴트 메소드 안에서만 호출이 가능합니다.

   ▷ private 정적 메소드는 정적 메소드 안에서도 호출이 가능합니다. 

   ▷ interface의 private 메소드는 java8버전에서는 적용이 안됩니다.

 

1. Service 인터페이스
public interface Service {
	default void defaultMethod1() {
		System.out.println("defaultMethod1 종속 코드");
		defaultCommon();
	}
	
	default void defaultMethod2() {
		System.out.println("defaultMethod2 종속 코드");
		defaultCommon();
	}
	
	private void defaultCommon() {
		System.out.println("defaultMethod 중복 코드A");
		System.out.println("defaultMethod 중복 코드B");
	}
	
	static void staticMethod1() {
		System.out.println("defaultMethod1 종속 코드");
		staticCommon();
	}
	
	static void staticMethod2() {
		System.out.println("defaultMethod2 종속 코드");
		staticCommon();
	}
	
	private static void staticCommon() {
		System.out.println("staticMethod 중복 코드C");
		System.out.println("staticMethod 중복 코드D");
	}
}​

 

2. ServiceImpl 클래스

public class ServiceImpl implements Service {
}​

 

3. ServiceExample 메인 클래스
public class ServiceExample {
	public static void main(String[] args) {
		Service service = new ServiceImpl();
		
		service.defaultMethod1();
		System.out.println();
		service.defaultMethod2();
		System.out.println();
		
		Service.staticMethod1();
		System.out.println();
		Service.staticMethod2();
		System.out.println();
	}
}

//	출력 :
//	defaultMethod1 종속 코드
//	defaultMethod 중복 코드A
//	defaultMethod 중복 코드B
//	
//	defaultMethod2 종속 코드
//	defaultMethod 중복 코드A
//	defaultMethod 중복 코드B
//	
//	defaultMethod1 종속 코드
//	staticMethod 중복 코드C
//	staticMethod 중복 코드D
//	
//	defaultMethod2 종속 코드
//	staticMethod 중복 코드C
//	staticMethod 중복 코드D


java19 버전에서는 바로 적용되네요!!

 

인터페이스의 개념은 추상이랑 비슷합니다. 하지만 객체가 값을 불러올 때 중간 매개체의 역할을 한다고 합니다.

그러니 객체는 굳이 원하는 값만 불러오고 인터페이스에서 찾아서 값을 보내줍니다.

 

이렇게 정리가되고 일단은 다음으로 넘어가보겠습니다!

 

많은 분들의 피드백은 언제나 환영합니다! 많은 댓글 부탁드려요~~

 

728x90
반응형

'BackEnd > Java' 카테고리의 다른 글

[java] 이것이 자바다 ch09 중첩 선언  (0) 2023.01.17
[java] 인터페이스2  (0) 2023.01.16
[java] 추상 클래스  (0) 2023.01.16
[java] 이것이 자바다 ch07 상속3  (0) 2023.01.13
[java] 이것이 자바다 ch07 상속2  (0) 2023.01.13