[OOP] 추상 클래스와 인터페이스

임수정·2024년 7월 12일
0

📝 Learning Log

목록 보기
41/47
post-thumbnail

📍 추상 클래스(Abstract Class)

추상 클래스란, 미완성된 클래스를 말한다.
클래스가 미완성이라는 것은 추상 메소드(미완성된 메소드)를 포함하고 있다는 것을 뜻한다. 추상 클래스의 목적은 자식 클래스에서 공유할 수 있도록 추상 클래스(부모 클래스)의 공통적인 정의를 제공하는 것이다. 추상 클래스 안에서 선언되는 모든 멤버변수, 메소드, 프로퍼티, 이벤트 들은 접근 제한자를 적지 않으면 모두 private이다.

하나 이상의 추상 멤버(메서드, 속성 등)을 포함할 수 있는 클래스이다. 추상 멤버는 선언만 되어 있고, 구현이 없는 메서드나 속성이다. 추상 클래스는 'abstract' 키워드를 사용하여 선언한다.
일반 클래스처럼 필드, 속성, 메서드를 포함할 수 있다. 하지만 추상 메서드가 하나라도 포함되면 클래스 자체도 추상 클래스가 되어야 한다. 추상 클래스를 상속받는 자식 클래스에서는 모든 추상 멤버를 반드시 구현해야한다.

추상 클래스는 일종의 미완성 설계도이다. 예를 들어, '동물'이라는 추상 클래스가 있다면 모든 동물들은 먹는 방법과 자는 방법을 갖고 있어야한다는 기본적인 설계가 있다. 그런데 각 동물들이 어떻게 먹고 자는지는 각자의 특성에 맞춰서 다르게 구현할 수 있다.

추상 클래스는 일종의 템플릿이라고 생각할 수 있다. 기본적인 구조를 제공하면서, 구체적인 기능은 나중에 상속받은 클래스들이 정의할 수 있게 해준다. 이 추상 클래스는 이러한 다양성을 효과적으로 관리할 수있게 도와준다.

추상클래스는 공통적인 기능을 제공하면서도, 특정 기능을 상속받은 클래스에서 구체화하고자 할 때 사용한다.

📍 인터페이스(Interface)

인터페이스는 추상클래스처럼 완성되지 않은 불완전한 것이고 추상 클래스보다 추상화 정도가 높다.
메서드, 속성, 이벤트 등의 추상 멤버들로 구성된다. 이들 멤버는 선언만 있고 구현은 없다. 또한 인터페이스는 다중상속이 가능해서 여러 인터페이스를 동시에 구현할 수 있다. 이는 클래스가 다양한 형태의 동작을 갖게 해주며 코드의 재사용성과 유연성을 높여준다.
인터페이스를 구현하는 클래스는 인터페이스에 정의된 모든 멤버(메서드, 속성 등)를 반드시 구현해야한다. 이를 통해 다양한 클래스들이 동일한 인터페이스를 구현하더라도 사용 방법을 일관되게 유지할 수 있다.

인터페이스는 일종의 계약서이다. 전기 기술자, 배관 기술자, 그리고 건축가가 모여서 집을 지을 때 각각의 전문가가 무엇을 해야하는지에 대한 계약서가 필요한데, 이러한 계약서 역할을 인터페이스가 한다. 인터페이스는 어떤 객체들이 가져야하는 기능들을 정의하는 일종의 명세서라고 생각하면 된다.

예를 들어, 자동차 인터페이스가 있다면 모든 자동차는 운전을 할 수 있어야 하고, 멈출 수 있어야 한다는 규칙을 정하고 이 인터페이스를 구현하는 모든 자동차들은 반드시 이 기능을 가지고 있어야 한다. 그래야 자동차라는 것을 보장받을 수 있다.

인터페이스는 클래스들이 구현해야 하는 메서드들의 규약을 정의하고, 다양한 객체들이 동일한 동작을 보장받게 해야할 때 사용한다.

📖 코드 결합도

인터페이스는 코드의 결합도를 낮출 수 있다. 결합도란 한 요소가 다른 요소와 얼마나 강하게 연결되어 있는지를 나타내는 개념이다. 인터페이스를 사용하면 클래스나 모듈간의 직접적인 의존성을 줄이고, 대신에 인터페이스를 통해 상호작용할 수 있다.

<장점>

  1. 유연성 증가: 인터페이스를 사용하면 구현을 쉽게 교체할 수 있다. 예를 들어, 한 클래스가 특정 인터페이스를 구현하면, 이 인터페이스를 사용하는 다른 클래스는 그 구현체가 무엇인지 신경 쓸 필요가 없다. 이는 코드를 유연하게 만들어 변경과 유지보수를 쉽게 할 수 있다.

  2. 의존성 관리: 인터페이스를 사용하면 각 모듈이나 클래스가 다른 모듈이나 클래스에 직접 의존하지 않고 인터페이스에만 의존하게 된다. 이는 코드의 결합도를 낮추어서 각 요소가 독립적으로 개발, 테스트, 유지보수될 수 있게 한다.

  3. 테스트 용이성: 인터페이스를 사용하면 테스트 작성이 쉬워진다. 특정 인터페이스를 구현한 클래스에 대한 테스트를 작성할 때, 해당 인터페이스를 구현한 다른 클래스를 사용하여 쉽게 모의 객체(Mock Object)를 생성할 수 있다.

  4. 시스템 확장성 : 새로운 기능이나 변경 사항이 발생했을 때, 인터페이스를 통해 기존 코드 수정 없이 새로운 구현을 추가할 수 있다. 이는 시스템 확장성을 높이고, 코드 변경이 다른 부분에 미치는 영향을 줄인다.

▶ 참고자료

📍 추상 클래스 VS 인터페이스

① 구현 내용의 유무

  • 추상 클래스 : 추상 메서드(구현이 없는 메서드) 외에도 일반 메서드나 멤버 변수 등을 포함할 수 있다. 즉, 일부 기능은 구현되어 있을 수 있다. 그렇기 때문에 특정 기능을 하위 클래스에서 확장하거나 수정할 수 있다는 장점이 있다.
  • 인터페이스 : 메서드의 선언만을 포함하고 있으며, 어떠한 구현 내용도 가지지 않는다. 즉, 메서드의 시그니처(이름, 매개변수, 반환 타입)만 정의된다.

② 다중 상속 가능 여부

  • 추상 클래스 : 추상 클래스는 클래스의 한 종류이기 때문에 단일 상속만 지원한다.

    📁 추상 클래스는 단일 상속을 지원하는 이유

    이는 다중 상속에서 발생할 수 있는 다양한 복잡성과 충돌을 방지하기 위한 설계 결정이다. 단일 상속은 클래스 간의 계층 구조를 간결하게 유지하고, 코드의 이해와 유지보수를 쉽게 만드는데 도움이 된다.

  • 인터페이스 : 다중 상속을 지원한다. 여러 개의 인터페이스를 한 번에 구현할 수 있다.

    📁 다중 상속을 지원하는 인터페이스의 주요 이점

    1. 클래스가 여러 인터페이스를 구현함으로써 각 인터페이스가 제공하는 다양한 기능들을 조합하여 사용 가능
    2. 인터페이스를 통해 다양한 객체들이 동일한 동작을 보상받을 수 있으며, 이는 코드의 유연성과 재사용성을 높이는데 도움을 준다.
    3. 클래스의 계층 구조를 파괴하지 않고 확장할 수 있는 방법을 제공한다. 인터페이스는 다중 상속을 하면서 여러개를 구현할 수 있어서 다양한 특성을 확장할 수있다.

③ 사용 목적

  • 추상 클래스 : 공통된 기능을 가진 클래스들의 구현을 재사용하며, 확장하여 특정 기능을 추가 할 때 사용
  • 인터페이스 : 다양한 객체들이 특정 메서드들을 반드시 구현하도록 하고, 이를 통해 코드의 일관성을 유지하거나 다형성을 구현하는데 사용

📍 요약

특성추상 클래스(Abstract Class)인터페이스(Interface)
정의추상 메서드&일반 메서드 포함 가능추상 메서드만 포함 가능
다중상속단일 클래스만 상속 가능여러 인터페이스 구현 가능
구현 상태추상 메서드와 일반 메서드를 포함할 수 있음모든 메서드가 추상 메서드이며, 디폴트 메서드를 포함할 수 있음
용도와 설계공통된 기능을 추출하여 상속을 통한 재사용성을 높임동일한 동작을 갖는 객체들을 정의하여 다형성을 촉진함(코드 결합도를 낮춤)
관계"is-a" 관계를 모델링함"can-do" 관계를 정의함
사용 예시특정 클래스들 사이에서 공통적인 메서드를 추출하여 확장함객체들이 공통된 동작을 수행하도록 정의함

is-a 관계
상속을 통한 부모 클래스의 모든 특성을 자식 클래스가 상속받고, 확장하여 사용하는 관계
클래스들 간의 일반적인 계층 구조를 형성하며 "X is Y" 형태로 설명

can-do 관계
인터페이스를 통해 객체들이 동일한 동작을 수행할 수 있도록 정의하는 관계
클래스들 간의 다형성(polymorphism)을 지원하며 "X can do Y" 형태로 설명

profile
언어는 거들 뿐...

0개의 댓글