☕Java: 인터페이스, 추상화, 느슨한 결합

yoondgu·2022년 3월 27일
0

Java 

목록 보기
7/18

강의 수강 중 작성한 노트에서 내용을 발췌, 이응수 강사님 강의 의 노트와 이미지를 참조하고 있습니다.
스스로 이해를 위해 직접 쓴 문장들의 경우 정확성이 떨어질 수 있다는 점 참고 부탁드립니다.

📌 인터페이스의 형식

  • 인터페이스의 이름은 형용사로 작성한다.
  • 상수의 표현: public static final 키워드를 생략할 수 있다.
  • 추상메소드의 표현: public abstract 키워드를 생략할 수 있다.
  • 구현 클래스에서 인터페이스 구현하기
    • 추상클래스 상속과 마찬가지로, 구현하기로 한 인터페이스의 추상메소드를 모두 구현메소드로 재정의해줘야 한다.
      • 인터페이스 하나 구현: 클래스명 뒤에 implements 인터페이스명
      • 인터페이스 여러 개 구현: 클래스명 뒤에 implements 인터페이스명1, 인터페이스명2...
public interface SampleInterface1 {
				public static final int MAX_UPLOAD_FILE_SIZE = 1024*1024*10; // 상수를 표함할 수 있다.
				int MAX_ONCE_UPLOAD_FILES = 5; // public static final을 생략할 수 있다.
				
				public abstract void saveFile(String directory, String filename); // 추상메소드 포함 가능
				void downloadFile(String directory, String filename); // public abstract 생략 가능 
}

public interface SampleInterface2 {
				void copy(File src, File dest);
				void copy(InputStream src, OutputStream dest);
}

// 구현 클래스에서 인터페이스 구현하기

💡 자식객체의 접근제한자 또한 재정의가 가능한데, 부모객체의 접근제한자와 같거나, 더 느슨해야 한다.


📌 인터페이스의 활용

  • 인터페이스를 이용해서 하위 클래스의 사용법을 통일시킬 수 있다.
  • 인터페이스를 이용하면 클래스 개발자와 클래스 사용자의 협업이 쉬워진다.
  • 개발시간을 단축시킬 수 있다.
  • 표준화가 가능하다.
    • 프로젝트에서 사용되는 구현클래스에 대한 기본 틀(기본 설계도)을 인터페이스로 작성한다.
    • 개발들에게 인터페이스를 기본 설계도로 삼아서 구현하게 하면 일관되고, 정형화된 프로그램 개발이 가능하다.
  • 인터페이스를 사용하면 클래스간의 관계를 느슨하게 유지할 수 있다.
    • 클래스간의 관계가 느슨하면 다른 클래스로 교체할 때, 수정할 코드가 줄어든다.

💡 자주 보는 인터페이스
Serializable : 직렬화 할 수 있는 인터페이스
Comparable : 비교 가능한 인터페이스
이런 인터페이스들을 보면 그 객체가 어떤 기능을 가지고 있는지 알 수 있다.

📌 인터페이스와 추상화

  • 추상클래스에서의 인터페이스 구현
    - 추상클래스는 부모 인터페이스에서 상속받은 추상메소드를 재정의할 필요가 없다.
    ⇒ 추상클래스는 구현클래스의 구현 부담을 감소시킨다.
    (인터페이스와 구현클래스 사이에 위치함으로써 구현클래스가 필요한 것만 재정의할 수 있게끔한다.)
    1. 인터페이스: 추상메소드를 보유
    2. 추상클래스: 인터페이스의 추상메소드 중, 하위 구현클래스들에서 구현내용이 전부 공통된 일부 기능만 구현메소드로 재정의한다. 나머지 추상메소드들은 구현클래스가 재정의하게 된다.
    3. 구현클래스: 상위 추상클래스의 추상메소드들을 각 객체마다 다른 구현내용으로 재정의
      ⇒ 많은 클래스들이 이런 구성을 활용한다.
        
  • 인터페이스 분리 원칙
    • 다중 상속, 다중 구현이 가능하기 때문에,
      부가적인 기능을 여러 개의 인터페이스로 분리하여 특정 객체에서 원하는 특정 기능만 구현하도록 할 수 있다.
      ⇒ 추상화된 기능들을 여러 인터페이스로 나누어서 조합할 수 있도록 한다.
      ⇒ 구현클래스가 특정 인터페이스를 구현한다는 것은, 그 인터페이스에 추상화된 기능을 구현해서 제공한다는 것을 뜻한다.
  • 인터페이스를 구현하는 클래스의 형변환

    • 인터페이스 타입의 참조변수에 인터페이스를 구현하는 객체의 참조값을 저장할 수 있다.
      • 구현 클래스가 여러 개의 인터페이스를 구현했을 때,
        그중 하나의 부모 인터페이스 타입참조변수구현 클래스를 연결한다면
        다른 부모 인터페이스로부터 구현한 기능은 사용할 수 없게 된다.

📌 인터페이스와 객체지향 설계 원칙

  • 의존성 역전 (Inversion of Control) 자신이 사용할 객체의 생성 책임을 제 3자가 가지고 있는 것. 느슨한 결합으로 객체를 연결한다.
    • 의존성 주입 (DI: Dependency Injection)
      • 제 3자가 내가 사용할 객체를 주입해준다.
      • 의존성 주입을 위한 환경:
        • 참조변수 + 인자값을 받는 생성자메소드 또는
        • 참조변수 + Setter메소드
      • 직접 객체를 생성하고 값을 저장하는 것이 아니라, 여러 객체들 간의 저장 상호작용을 의존적으로 수행하는 것 ⇒ 의존 역전 원칙
      (추후 배울 스프링 프레임워크에서는 훨씬 편하게 처리하도록 되어있다.)
    • 의존성 검색 (DL: Dependency Lookup)
      • 제 3자가 내가 사용할 객체를 생성해 놓으면 그 중에서 필요한 객체를 찾아서 사용한다.

💡 객체지향 설계 5원칙 SOLID는 인터페이스와 아주 밀접한 연관을 가진다.

  • SRP(Single Responsibility Principle): 단일 책임 원칙
  • OCP(Open Closed Priciple): 개방 폐쇄 원칙
  • LSP(Listov Substitution Priciple): 리스코프 치환 원칙
  • ISP(Interface Segregation Principle): 인터페이스 분리 원칙
  • DIP(Dependency Inversion Principle): 의존 역전 원칙

클래스가 인터페이스에 의존하게 만들면, 클래스와 인터페이스를 구현한 클래스들 간에는 느슨한 결합이 형성된다.
꼭 모든 것을 느슨한 결합으로 프로그래밍을 해야하는 것은 아니다. 업무 케이스에 따라 다를 것이다. 하지만 언제, 왜 이런 방식의 구현이 필요한지 알아야 한다.

  • 자바라이브러리는 어떤 경우에도 사용할 수 있도록, 객체를 직접 수정할 필요 없도록 느슨한 결합으로 만들어져 있다.

0개의 댓글