인터페이스와 인터페이스와 추상클래스의 차이점

GoldenDusk·2023년 11월 20일
0

CS지식

목록 보기
20/26
post-thumbnail

인터페이스

🔗 출처 : https://www.youtube.com/watch?v=a6F7rIKaxzo

🍈 인터페이스의 정의

인터페이스는 상호작용을 위해서 미리 정의된 약속으로, 서로 다른 모듈이나 시스템을 연결하고 기능을 사용하기 위한 도움미 역할을 하는 것이다. 마치 컴퓨터를 키기 위해 전원을 누르는 것과 같은 것으로 여기서는 전원 버튼인터페이스로서 컴퓨터를 켜는 역할을 한다. 실생활에서 무의식 가운데 쓰는 것들이 인터페이스

  • 예를 들어 A라는 함수라는 호출하면 B라는 결과 도출되는 것이 인터페이스다. 즉, 컴퓨터의 파워 전원 버튼, 변기의 레버 등이 인터페이스가 될 수 있다.
  • 즉, 인터페이스란 서로 다른 시스템이나 기능을 연결하여 사용할 수 있게 도와준다.
  • 인터페이스는 인터페이스를 구현하는 모든 클래스에 대해 특정한 메소드가 반드시 존재하도록 강제한다.

🤔 그렇다면.. 덩치가 큰 인터페이스 API는 뭘까? API와 인터페이스와의 연계

  • Application Programming Interface의 약자로 제조사가 그 기능을 개발에 잘 쓰게 만들기 위해서는 사용자한테 제공해주는 프로그램이나 코드의 세트를 의미하는 인터페이스
  • 구글 인앱 API를 사용하여 개발한다면 우리의 앱과 구글 인앱 결제 사이를 이어주는 인터페이스가 API가 되는 것이고 이 중간에 있는 것들은 뭐든지 인터페이스
  • 키보드 같은 존재
  • 키보드는 컴퓨터를 대화를 하고 스크린으로 텍스트를 볼 수 있음
  • 즉, 키보드를 통해서 컴퓨터와 인터랙션을 함(키보드로 정보를 입력하는 것)
  • API란 프로그램들이 서로 소통하는 방법, 인간이 아닌 코드들끼리 소통하기 위해 만들어진 것으로 서버에서 만든 것
  • API는 데이터, 서버를 갖고 있는 사람들이 원하는 대로 디자인 가능
  • 많은 종류들의 API들은 다른 목적을 가지고 있지만 같은 작업을 함 ⇒ 버튼을 보여주고, 나의 코드로 그것을 누를 수 있고 원하는 작업을 수행 가능

EX.

키보드를 IOS 앱에 줌 ⇒ 규칙을 정해줌 이 키는 업로드 ⇒ 이렇게 되면 키의 입력을 받으면 백엔드 데이터베이스나 서버에 가서 알려줌

🤔 그렇다면 RestAPI, GraphQL API는 뭘까?

  • 그냥 다르게 생긴 키보드들임
  • 같은 목적을 달성 ⇒ 프로그램 소통하게 해줌
  • 앱과 서버와 소통할 수 있는 키보드

🍈 인터페이스의 사용

  • 인터페이스의 목적은 구현 객체가 같은 동작을 한다는 것을 보장하는 것이다.
  • 일종의 추상 클래스다. 하지만 추상 클래스보다 추상화 정도가 높아서 추상 메소드 이외의 일반 메소드나 멤버 변수를 구성원으로 가질 수 없다.오직 추상 메소드와 상수만 멤버로 가질 수 있으며, 그 외의 요소는 허용하지 않는다.
  • 추상 클래스를 부분적으로만 완성된 미완성 설계도라고 한다면 인터페이스는 구현된 것이 아무것도 없는 기본 설계도라 할 수 있다.
  • 제약 사항
    • 모든 멤버 변수는 public static final 이어야 하며, 생략 가능.
    • 모든 메소드는 public abstract 이어야 하며, 생략 가능.
    • JDK 1.8부터 인터페이스에 static 메소드와 디폴트 메소드의 추가를 허용했다.
interface PlayCard {
  public static final int NUMBER = 4;

  final int DIAMOND = 3;
  static int HEART = 2;
  int CLOVER = 1;
  // 위의 상수는 모두 public static final이며, 생략된 형태이다.

  public abstract int getCardNumber();

  String getCardKind();

  // public 생략.
  default void getNewCard() {

  }

  // public 생략.
  static void staticMethod() {

  }
}

🍈 인터페이스 만들 때 고려해야 할 상황

1. 직관적인 입출력[Simple is best]

예를 들어… 1초에 벨을 3번 눌러야만 반응하는 호출벨이라던지는 안좋다.. 결국 이런 것이 코드에 적용되면 안 좋은데 특정 순서대로 호출해야만 동작하는 함수라든지 우리가 아는 특정 값을 파라미터로 넘겨야만 동작하는 함수라든지는 안 좋다… ⇒ 주석이 면죄가 되지 않는다.. 즉 클린 코드의 중요성

2. 명확하게 설계

호출벨을 누르면 직원이 오는 것 처럼, 함수도 마찬가지로 호출하면 결과가 뭔가 리턴된다라고 되는 것이 좋은 인터페이스

3. 예외 상황에 대한 처리

  • 성능 요구사항과 같이 마치 호출벨이라고 생각하면 우리가 음식점에서 호출벨을 눌렀는데 10초이상 아무도 대답하지 않는다면… 안된다. 뭐 바쁘다면 잠시만요라든지, 아니면 대답이라도 있어야 한다. 즉, 예외 상황에 대한 처리 언제까지 어떤 결과가 오든, 에러가 리턴이 돼서 사용자가 알게 해야한다.

4. 중요 : 하위호환지원

음식점을 예시로 들자면, 음식점에 갔는데 저기요라고 부르는데 직원이 자신을 보고 있음에도 오지 않았고 여러번 부르니 을 눌러야지 가죠라고 얘기를 한다면… 저기요는 구버전 인터페이스임에도 기분 나빠서 가지 않게 됨… 즉, 둘 다 지원하는 것이 맞음

  • 신버전 인터페이스가 있음에도 구버전 인터페이스를 지원하는 것

⇒ MS가 잘해서 운영체제 독점하는 이유 : 이전 OS에서 돌아가는 프로그램들이 웬만하면 신 OS에서 다 돌아간다.

  • 오히려 신제품 개발에서 발목이 잡히기도 함
  • 그러나 지원을 안한다면 회사의 신뢰도가 떨어질 수 있음
  • 즉, 회원 지원과 관리는 균형을 잘 맞춰야 하며, 개발자는 회원 지원과 관리를 고민하며, 사용자들은 회원 지원이 제대로 이루어지길 바란다.

5. 쉬운 접근성과 대중성

  • 누구나 아는 것이어야 한다.
  • 사용자들이 쉽게 이해하고 사용할 있어야 하며, 사용자들이 쉽게 접근하고 사용할 수 있어여 한다.

🍈 인터페이스의 상속

  • 인터페이스는 인터페이스로부터만 상속(extends) 받을 수 있다. 클래스와는 달리 다중 상속, 즉 여러 개의 인터페이스로부터 상속 받는 것이 가능하다.
  • 클래스에서 여러 인터페이스를 다중 구현하는 것 또한 가능하다.

🍈 인터페이스의 구현

  • 추상 클래스와 마찬가지로 자신이 직접 인스턴스를 생성할 수 없다. 따라서 인터페이스가 포함하고 있는 추상 메소드를 구현해 줄 클래스를 작성해야 한다.
  • 상속은 클래스를 확장한다는 의미의 키워드인 extends를 사용하며, 인터페이스는 구현한다는 의미의 키워드인 implements를 사용한다.
interface Movable {
  void move(int x, int y);
}

interface Attackable {
  void attack(Unit n);
}

interface Fightable implements Movable, Attackable {

}

abstract class Fighter implements Fightable {
  public void move(int x, int y){
    ...
  }
}

만약 모든 추상 메소드의 구현을 원하지 않는다면 위의 코드처럼 Fighter 클래스를 abstract 키워드를 붙여 추상 클래스로 선언해야 한다.

위에서는 move() 함수만을 구현했다. attack()을 구현하지 않았기 때문에 abstract Fighter인 추상 클래스로 선언을 했다.

자바에서는 상속과 구현을 동시에 할 수 있다.

class Fighter extends Unit implements Fightable {
  public void move(int x, int y) { ... }
  public void attack(Unit u) { ... }
}

🍈 클래스를 이용한 다중 상속의 문제점

  • 다중 상속이 된다고 가정했을 때, 아래의 코드를 확인해보자.
class Animal {
  public void cry(){
    System.out.println("짖기!");
  }
}

class Cat extends Animal {
  @Override
  public void cry(){
    System.out.println("냐옹냐옹!");
  }
}

class Dog extends Animal{
  @Override
  public void cry(){
    System.out.println("멍멍!");
  }
}

class MyPet extends Cat, Dog { ... }
// 1.

public class Test {
  public static void main(String[] args){
    MyPet pet = new MyPet();
    pet.cry();
    // 2.
  }
}

다중 상속을 허용할 경우, 발생할 수 있는 문제는 메소드 출처의 모호성이다.

주석을 달아놓은 2에서 MyPet 클래스의 인스턴스인 pet이 cry() 메소드를 호출하면 이 메소드가 Dog 클래스의 cry() 메소드인지, Cat 클래스의 cry() 메소드인지 구분할 수 없는 모호성이 생긴다.

이와 같은 이유로 자바에서 다중 상속을 지원하지 않는다.

하지만, 인터페이스를 이용해 다중 구현을 하게되면 위와 같은 메소드 호출의 모호성을 방지할 수 있다.

interface Animal {
  void cry();
}

interface Cat extends Animal {
  void cry();
}

interface Dog extends Animal {
  void cry();
}

class Pet implements Cat, Dog {
  @Override
  public void cry(){
    System.out.println("멍멍~ 냐옹냐옹~")
  }
}

public class Test{
  public static void main(String[] args){
    Pet pet = new Pet();
    pet.cry();
  }
}

// 결과
멍멍~ 냐옹냐옹~

Cat, Dog 인터페이스를 동시에 구현한 Pet 클래스에서만 cry() 메소드를 정의하므로, 앞의 예제에서 발생한 메소드 호출의 모호성이 없다.

🍈 인터페이스를 통한 다형성

자손 클래스의 인스턴스를 조상 타입의 참조 변수로 참조하는 것이 가능하다.

인터페이스도 인터페이스를 구현한 클래스의 조상이라고 할 수 있으므로, 해당 인터페이스 타입의 참조 변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있다.

장점

  1. 대규모 프로젝트 개발 시 일관되고 정형화된 개발을 위한 표준화가 가능하다.
  2. 클래스의 작성과 인터페이스의 구현을 동시에 진행할 수 있으므로, 개발 시간을 단축할 수 있다.
  3. 클래스와 클래스 간의 관계를 인터페이스로 연결하면 클래스마다 독립적인 프로그래밍이 가능하다.

추상 클래스와 인터페이스의 차이점

🍈 인터페이스**(Interface)**

1. 정의

  • 클래스가 아니며, 클래스와 관련이 없다. 단순히 추상 메소드상수(상수 변수)만을 멤버로 이루어진 일종의 계약(Contract)이다.

2. 특징

  • 다중 구현 가능: 클래스가 여러 인터페이스를 구현할 수 있다. 이는 자바에서 다중 상속을 허용하지 않는 대신 인터페이스를 통해 유연하게 다중 구현이 가능하게 한다.
  • default 메소드 (Java 8 이후): default 키워드를 사용하여 메소드에 기본 구현을 제공할 수 있다. 이는 인터페이스를 수정할 때 구현체를 변경하지 않아도 되게끔 한다.
  • static 메소드 (Java 8 이후): static 메소드를 인터페이스에 선언할 수 있다. 주로 유틸리티성 메소드를 정의하는 데 사용된다.

3. 용도

  • 구현 객체의 같은 동작을 보장하기 위해 사용한다. 러 클래스에서 동일한 인터페이스를 구현함으로써 특정 동작이 보장되게 할 수 있다.

🍈 추상 클래스**(Abstract Class)**

1. 정의

  • 클래스이며, 클래스와 관련이 있다. (주로 베이스 클래스로 사용)
  • 추상 메소드 및 일반 메소드와 멤버도 포함할 수 있다.

2. 특징

  • 상속을 통한 확장: 추상 클래스는 다른 클래스에게 기본 구조를 제공하고, 상속을 통해 기능을 확장시킬 수 있다.
  • 다중 상속 불가능: 하나의 클래스가 여러 개의 클래스를 상속받을 수 없다. 이는 자바에서 클래스 간의 다중 상속을 허용하지 않기 때문이다.

3. 용도

  • 기존의 클래스에서 공통된 부분을 추상화하여 상속하는 클래스에게 구현을 강제화한다. 메소드의 동작은 구현하는 자식 클래스로 위임한다. 공유의 목적을 갖는다.

🍈 공통점

인터페이스와 추상 클래스 모두 객체지향 프로그래밍(OOP)의 원칙을 따르며, 코드의 재사용성과 유지보수성을 향상시키는 데 기여한다.

profile
내 지식을 기록하여, 다른 사람들과 공유하여 함께 발전하는 사람이 되고 싶다. gitbook에도 정리중 ~

0개의 댓글