본문 바로가기

복습

[Java 복습] 인터페이스의 장점

인터페이스의 장점

  • 두 대상(객체) 간의 연결, 대화, 소통을 돕는 중간 역할을 한다.
  • 선언(설계)와 구현을 분리시킬 수 있게 해준다.
  • 인터페이스 덕분에 구현부가 바뀌어도 선언부는 안 바꿀 수 있게 된다.(느슨한 결합) => 변경에 유리
  • 껍데기 + 알맹이로 분리해놓으니 유연한 코드가 되고 변경에 유리해진다.
  • 느슨한 결합은 인터페이스를 한번 거치기 때문에 한 단계 느리겠지만 변경에 유리하고 유연한 코드가 된다.

 

 

직접적인 관계의 두 클래스(A-B)

class A {
    public void methodA(B b) {
        b.methodB(); // B 클래스의 메서드호출
    }
}
class B {
    public void MethodB() {
        System.out.println("methodB()");
    }
}
class InterfaceTest { 
    public static void main(String args[]) {
        A a = new A();
        a.methodA(new B());
    }
}

 

 

간접적인 관계의 두 클래스(A- | -B)

Interface I { //껍데기 분리
    void methodB();
}
class B implements I { //알맹이 분리
    public void methodB() {
        System.out.println("methodB()");
    }
}
class A {
    public void methodA(I i) { // I를 사용하게 바꿈. 더이상 A는 B클래스와 관계없음.(Interface 관계 o)
        i.methodB();
    }
}

 

 

 

정리

class A {
    public void method(B b) { 
        b.method();
    }
}

class B {
    public void method() {
        System.out.println("B 클래스의 메서드");
    }
}

public class InterfaceTest {

    public static void main(String[] args) {
        A a = new A();
        a.method(new B()); // A가 B를 사용(A가 B에 의존하고 있다.)
    }
}
class A {
    public void method(C b) {  // 참조 타입 C 로 변경
        b.method();
    }
}

class B {
    public void method() {
        System.out.println("B 클래스의 메서드");
    }
}

class C { // 새로 추가된 클래스 A가 C를 의존하게 하려고 함(두 곳을 수정해야 함!!)
    public void method() {
        System.out.println("C 클래스의 메서드");
    }
}

public class InterfaceTest {

    public static void main(String[] args) {
        A a = new A();
        a.method(new C()); // A가 C를 사용(A가 C에 의존하고 있다.) 변경
    }
}
class A {
    //public void method(C c){ } 
    public void method(I i) { // 인터페이스 I를 구현한 넘들만 들어올 수 있음.
        i.method();
    }
}

// B클래스의 선언과 구현을 분리
interface I {
    public void method();
}

class B implements I{
    public void method() {
        System.out.println("B 클래스의 메서드");
    }
}

class C implements I{
    public void method() {
        System.out.println("C 클래스의 메서드");
    }
}

public class InterfaceTest {

    public static void main(String[] args) {
        A a = new A();
        a.method(new B()); // A가 B를 사용(A가 B에 의존하고 있다.)
        a.method(new C());
    }
}

 

 

1. 개발 시간을 단축할 수 있다.

 

  • A를 사용하기 위해서는 B가 만들어져 있어야 한다!
  • B가 아직 개발되지 않았어도 I(인터페이스)만 있으면 된다!
    • 추상 메서드 호출 가능
  • 그럼 iv(인스턴스 변수)가 필요한 경우 어떻게 접근해서 A를 만들어요?
    • iv는 보통 캡슐화라는 개념을 통해 private으로 만들어진다 => 항상 메서드를 통해서 접근하게 된다.
    • 결론적으로 A가 B클래스가 완성되지 않아도 인터페이스를 통해 코드를 작성할 수 있다.

 

2. 변경에 유리한 유연한 설계가 가능하다.

  • B를 없애고 C를 집어넣을 수 있다 => A의 변경이 없음!!!

 

 

3. 표준화가 가능하다. (JDBC)

JDBC(Java 표준 인터페이스 집합)를 중간 역할로 두고 자바프로그램은

거의 코드 변경없이 데이터베이스(자바 표준을 지킨 데이터베이스 한정)를 바꿀 수 있다.

(like USB 포트 규격 표준같이 서로 다른 회사끼리도 USB 포트와 선을 꼽을 수 있다.)

 

 

4.서로 관계없는 클래스들을 관계를 맺어줄 수 있다.

 

 

 

인터페이스에 디폴트 메서드, static 메서드 추가 가능(JDK 1.8 ~)

인터페이스에 새로운 메서드(추상 메서드)를 추가하기 어려움. =>

새로운 추상 메서드가 추가될 때마다 인터페이스를 구현하는 클래스 모두가 새로운 메서드를 구현해야함 =>

해결책: 디폴트 메서드 => 몸통이 있는 메서드를 해결책으로 나옴

interface MyIstance {
    void method();
    default void newMethod(){ //몸통 }
}

 

디폴트 메서드가 기존의 메서드와 충돌할 때의 해결책

  • 여러 인터페이스의 디폴트 메서드 간의 충돌
    • 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 한다.
  • 디폴트 메서드와 조상 클래스의 메서드 간의 충돌
    • 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.

'복습' 카테고리의 다른 글

[Java 복습] 예외처리  (1) 2024.05.02
[Java 복습] 내부 클래스  (0) 2024.05.02
[Java 복습] 다형성의 장점  (0) 2024.04.30
[Java 복습] 상속, 캡슐화, 다형성  (0) 2024.04.30
[Java 복습] 클래스와 메서드  (0) 2024.04.28