인터페이스(Interface)
1. detecter package
package chap_08.detecter;
public interface Detectable {
void detect(); // 감지를 진행하는 메서드
}
///////////////////////////////////////////////////////////////
package chap_08.detecter;
public class AdvancedFireDetector implements Detectable{
@Override
public void detect() {
System.out.println("향상된 성능으로 화재를 감지합니다.");
}
}
///////////////////////////////////////////////////////////////
package chap_08.detecter;
public class FireDetector implements Detectable{
@Override
public void detect() {
System.out.println("일반 성능으로 화재를 감지합니다.");
}
}
2. reporter package
package chap_08.reporter;
public interface Reportable {
void report(); // 신고를 진행하는 메서드
}
//////////////////////////////////////////////////////////////////
package chap_08.reporter;
public class NormalReporter implements Reportable{
@Override
public void report() {
System.out.println("신고를 진행합니다.");
}
}
//////////////////////////////////////////////////////////////////
package chap_08.reporter;
public class VideoReporter implements Reportable{
@Override
public void report() {
System.out.println("직전 30초 영상과 함께 신고를 진행합니다.");
}
}
3. interface package
package chap_08;
import chap_08.camera.FactoryCam;
import chap_08.detecter.AdvancedFireDetector;
import chap_08.detecter.Detectable;
import chap_08.detecter.FireDetector;
import chap_08.reporter.NormalReporter;
import chap_08.reporter.Reportable;
import chap_08.reporter.VideoReporter;
public class _02_Interface {
public static void main(String[] args) {
// 인터페이스
Reportable nr = new NormalReporter();
nr.report();
System.out.println("====================================");
VideoReporter vr = new VideoReporter();
vr.report();
System.out.println("====================================");
Detectable fireDetector = new FireDetector();
fireDetector.detect();
Detectable advendcedFireDetector = new AdvancedFireDetector();
advendcedFireDetector.detect();
System.out.println("====================================");
FactoryCam fc = new FactoryCam();
fc.setDetector(advendcedFireDetector);
fc.setReporter(nr);
fc.detect();
fc.report();
}
}
<response>
신고를 진행합니다.
====================================
직전 30초 영상과 함께 신고를 진행합니다.
====================================
일반 성능으로 화재를 감지합니다.
향상된 성능으로 화재를 감지합니다.
====================================
향상된 성능으로 화재를 감지합니다.
신고를 진행합니다.
1. 인터페이스란?
인터페이스는 객체의 사용 방법을 정의하는 타입입니다. 인터페이스에는 메서드의 시그니처만 있고, 구체적인 구현은 없습니다. 이를 통해 다양한 객체가 동일한 인터페이스를 구현할 수 있습니다.
2. 인터페이스의 정의
public interface Detectable {
void detect(); // 감지를 진행하는 메서드
}
여기서 Detectable 인터페이스는 detect라는 메서드를 정의하고 있습니다. 이 메서드의 구체적인 동작은 인터페이스를 구현하는 클래스에서 정의됩니다.
3. 인터페이스의 구현
public class FireDetector implements Detectable{
@Override
public void detect() {
System.out.println("일반 성능으로 화재를 감지합니다.");
}
}
FireDetector 클래스는 Detectable 인터페이스를 구현(implements)합니다. 이 클래스는 detect 메서드를 오버라이드하여 구체적인 동작을 정의합니다.
4. 다양한 구현
동일한 인터페이스를 여러 클래스가 구현할 수 있습니다. 예를들어, AdvancedFireDetector 클래스도 Detectable 인터페이스를 구현하고 있으며, detect 메서드의 동작을 다르게 정의하고 있습니다.
5. 다른 인터페이스의 예
Reportable 인터페이스는 report라는 메서드를 정의하고 있습니다. 이 인터페이스도 NormalReporter와 VideoReporter 두 클래스에 의해 구현됩니다.
6. 인터페이스의 활용
Detectable fireDetector = new FireDetector();
fireDetector.detect();
Detectable advendcedFireDetector = new AdvancedFireDetector();
advendcedFireDetector.detect();
인터페이스 타입의 참조 변수를 사용하여 다양한 구현체의 인스턴스를 참조할 수 있습니다. 이를 통해 코드의 유연성과 확장성을 높일 수 있습니다.
7. 종합
인터페이스를 사용하면 여러 클래스가 동일한 인터페이스를 구현할 수 있으므로, 다양한 동작을 정의하면서도 일관된 사용 방법을 제공할 수 있습니다. 이를 통해 코드의 유연성과 재사용성을 높일 수 있습니다.
8. 궁금점
그러면 그러면 FireDetector fireDetector1 = new FireDetector(); 이거랑 Detectable fireDetector2 = new FireDetector(); 은 무슨 차이일까?
=> FireDetector fireDetector1 = new FireDetector();와 Detectable fireDetector2 = new FireDetector(); 사이의 주요 차이점은 변수의 선언 타입에 있습니다. 이 두 선언은 동일한 FireDetector 객체를 참조하지만, 그 참조 방식과 그 변수를 사용할 때의 유연성에 차이가 있습니다.
1) 타입에 따른 변수 사용의 제한
- FireDetector fireDetector1 = new FireDetector();: fireDetector1 변수는 FireDetector 클래스의 모든 메서드와 속성에 접근할 수 있습니다. 만약 FireDetector 클래스에 Detectable 인터페이스에 없는 추가 메서드나 속성이 있다면, 이 변수를 통해 그것들에 접근할 수 있습니다.
- Detectable fireDetector2 = new FireDetector();: fireDetector2 변수는 Detectable 인터페이스에 정의된 메서드만 호출할 수 있습니다. 실제 객체는 FireDetector이지만, 변수의 타입이 Detectable이므로 인터페이스에 정의된 메서드 외에는 호출할 수 없습니다.
2) 유연성
Detectable 타입의 변수를 사용하면 여러 구현 클래스 (예: FireDetector, AdvancedFireDetector 등)의 인스턴스를 참조할 수 있습니다. 이를 통해 코드의 유연성을 높일 수 있습니다. 예를 들어, 나중에 다른 타입의 감지기를 사용해야 할 때 fireDetector2 변수에 새로운 객체를 할당할 수 있습니다.
3) 다형성
Detectable fireDetector2 = new FireDetector();의 방식은 객체 지향 프로그래밍의 다형성 원칙을 따르고 있습니다. 이렇게 하면 여러 구현 클래스의 인스턴스를 동일한 인터페이스 타입의 변수로 참조할 수 있습니다. 이는 코드의 유연성과 확장성을 향상시키는 데 중요한 역할을 합니다.
요약하면, FireDetector fireDetector1 = new FireDetector();는 구체적인 클래스 타입을 사용하여 변수를 선언하는 반면, Detectable fireDetector2 = new FireDetector();는 인터페이스 타입을 사용하여 변수를 선언합니다. 후자의 방식은 다양한 구현 클래스의 인스턴스를 참조할 수 있으므로 코드의 유연성이 높아집니다.