인프런 커뮤니티 질문&답변

Ambition님의 프로필 이미지
Ambition

작성한 질문수

나도코딩의 자바 기본편 - 풀코스 (20시간)

인터페이스 (후반전)

구상클래스에서 인터페이스 변수를 선언한 이유가 혹시 다형성과 관련이 있나요?

해결된 질문

작성

·

420

0

 클래스의 상속과 관련된 다형성은 부모객체로 인스턴스를 생성하여 부모클래스의 메소드와 자식클래스 메소드 2가지를 업/다운캐스팅하여 자유롭게 호출할 수 있지만, 단일상속이라는 한계때문에 다른 부모클래스의 메소드는 호출할 수가 없잖아요? 그래서 인터페이스가 존재하는 이유구요.

마찬가지로, 인스턴스를 생성할 때 다형성을 활용하여 인터페이스 객체(부모 객체)로 생성할 수는 있지만, 이것은 ISP(Interface Segregation Principle)원칙에 따라 detect(), report() 2개의 메소드를 호출하려면 Detectable, Reportable 객체 2개를 생성해야 하기 때문에 메모리가 효율적으로 관리되지 못하는거구요. 따라서 구상클래스인 FactoryCam에서 인터페이스 변수를 직접 생성하고 setter함수로 필요한 인터페이스 변수를 주입한 다음(Dependency Injection) , 주입당한 객체는 인터페이스에 의존하기 때문에(Reportable, Detectable) 동시에 기능이 다른 2가지 메소드를 호출할 수 있는거구요.(Dependency Inversion Principle)

 

... 과정을 이해하였지만 말로 풀어내니까 굉장히 장황하군요 사실 이 부분은 인터페이스 문법이라기보다는 디자인 패턴과 관련이 있지 않나싶습니다.

답변 2

1

나도코딩님의 프로필 이미지
나도코딩
지식공유자

안녕하세요?
답변이 늦어 죄송합니다 🙇‍♂️

그렇습니다. 인터페이스와 다형성, 그리고 디자인 패턴들이 서로 어떻게 연결되어 프로그램을 유연하고 확장 가능하게 만드는지에 대해 잘 이해하고 계신 것 같아요.

자바에서 클래스는 단일 상속의 제약 때문에 다른 부모 클래스의 메소드를 직접 호출하기 어렵습니다. 이런 상황에서 인터페이스가 유용하게 활용될 수 있는데 인터페이스는 클래스와 달리 다중 구현이 가능하며, 여러 클래스가 공통적으로 갖는 동작을 정의하는데 사용되지요. 그리고 인터페이스를 이용하여 다른 클래스와의 결합도를 낮추고 유연한 코드를 작성할 수 있습니다.

강의에서 예시로 다룬 FactoryCam 의 경우 다음과 같이 2개의 인터페이스 변수를 선언하고 setter 를 마련해두었습니다.

// FactoryCam.java
private Detectable detector;
private Reportable reporter;

public void setDetector(Detectable detector) {
    this.detector = detector;
}

public void setReporter(Reportable reporter) {
    this.reporter = reporter;
}

그러면 Detectable 인터페이스를 구현하는 클래스로부터 만들어진 객체라면 무엇이든지 이렇게 설정할 수가 있는 것죠. (Reportable 도 동일합니다)

// FireDetector.java
public class FireDetector implements Detectable {
    @Override
    public void detect() {
        System.out.println("일반 성능으로 화재를 감지합니다.");
    }
}
// AdvancedFireDetector
public class AdvancedFireDetector implements Detectable{
    @Override
    public void detect() {
        System.out.println("향상된 성능으로 화재를 감지합니다.");
    }
}
// Main Method
factoryCam.setDetector(new FireDetector()); // 가능
factoryCam.setDetector(new AdvancedFireDetector()); // 가능

그러면 FactoryCam 의 detector 인터페이스를 사용하는 입장에서는 필요할 때 그냥 detect() 메소드를 호출하기만 하면 되는 것입니다. 이는 다형성에 의해 가능한 것이며 실제로는 어떤 객체의 detect() 메소드가 호출되는지는 알 수 없지만 주입된 객체는 모두 detect() 를 가지고 있으므로 이 메소드가 호출되는 것이죠. 예시에서는 일반 성능의 화재 감지일 수도 있고 향상된 성능의 화재 감지일 수도 있습니다. 또는 Detectable 인터페이스를 구현하는 또다른 객체도 얼마든지 될 수 있습니다.

궁금증 해결에 도움되길 바라겠습니다 😊
감사합니다.

Ambition님의 프로필 이미지
Ambition
질문자

자세히 설명해주셔서 감사드립니다 🙇‍♂️ Detector, Reporter 참조 객체 변수를 추가적으로 만들지 않고 인자에 원하는 클래스를 new로 넣는 방법은 좋은 것 같네요😊

디자인 패턴을 추가적으로 공부해서 클래스 간의 결합도를 낮추는 방법을 알아봐야겠어요

0

Ambition님의 프로필 이미지
Ambition
질문자

KakaoTalk_20230810_173246121.jpg이해를 돕기 위해 객체간의 관계도를 그려봤습니다

Ambition님의 프로필 이미지
Ambition

작성한 질문수

질문하기