.
본문 바로가기
TypeScript

abstract 와 interface 차이점

by 와칸다개발자 2021. 11. 8.

abstract 와 interface는 언뜻보면 비슷해보인다. 

 

그러나 둘은 명확한 차이가 있기에 차이점을 알아보자.

 

abstract class

 

추상클래스는 일종의 미완성 설계도이다. 상속을 통하여 인스턴스를 생성할 수 있으며

 

추상클래스 자체로 인스턴스를 생성할 수 없다. 추상클래스는 abstract 키워드를 붙여서 표현하며

 

abstract로 선언한 메소드는 자식클래스에서 반드시 구현해야 한다. 

 

  abstract class Person{
      private age:number;
      private name:string;

      constructor(a:number, n: string){
          this.age = a;
          this.name = n;
      }

      public abstract whereAreyouFrom():void;
  }

  // cannot create an instance of an abstract class
  // 추상클래스는 인스턴스를 생성할 수 없다.
  const p : Person = new Person();

  class American extends Person{
      public whereAreyouFrom(){
          return 'im american';
      }
  }

  class Japanese extends Person{
      public whereAreyouFrom(){
          return 'im japanese';
      }
  }

 

추상 클래스는 인스턴스를 생성할 수 없으며 abstract 키워드는 반드시 자식클래스에서 구현해야 한다.

 

Interface

 

인터페이스는 추상화가 더 높은 모든 메서드가 추상메서드인 경우를 말한다. (그래서 abstract를 적지 않는다.)

 

기본 설계도라 볼 수 있으며 다중상속이 가능하다.

 

  interface Person{
      name:string;
      age:number;

      getAge():number;
  }

  class American implements Person{
      name:string = 'sdsd';
      age:number = 23;

      public getAge():number{
          return this.age;
      }
  }

 

그래서 차이가???

 

추상클래스와 인터페이스는 공통적으로 추상메서드를 구현하도록 강제한다.

 

두개의 차이점은 사용용도이다.

추상클래스는 is 의 관계, 인터페이스는 has 의 관계

 

먼저 모든 클래스가 인터페이스를 구현받아 사용한다면 공통으로 구현해야할 메소드들을 

 

상속받는 모든 클래스에서 재정의하여야 한다. 

 

  interface Person{
      name:string;
      walk():void;
  }

  class American implements Person{
      name:string = 'sdsd';
      public walk(){
          console.log('person walk');
      }
  }

  class Japanese implements Person{
      name:string = 'roro';
      public walk(){
          console.log('person walk');
      }
  }
  // 추상클래스가 없는 세상에서 공통기능인 걷기 메소드를 일일이 다 구현해야한다.
  // 추상클래스에서 일반 메소드로 정의하여 상속하면 그럴일이 없는데 ~

 

추상클래스가 없는 저 평행지구 프로그래밍 세계에서는 공통기능인 걷기 구현의 차이가 없는 메소드를 일일이 다 구현해야한다.

추상클래스에서 일반 메소드로 정의하여 상속하면 그럴일이 없는데 ~

 

자세한 예시를 들어보자

 

  abstract class IronMan{
      public walk(){
          console.log('walk');
      }

	  // attack은 추상메소드로 반드시 자식클래스에서 구현
      public abstract Attack():void;
  }

  interface Flyable{
      fly():void;
  }

  interface Swimable{
      swim():void;
  }

  class Mark2 extends IronMan{
      public Attack(){
          console.log('2 attack');
      }
  }

  class Mark36 extends IronMan implements Flyable{
      public Attack(){
          console.log('36 attack');
      }

      public fly(){
          console.log('fly~~~');
      }
  }

  class Mark40 extends IronMan implements Swimable{
      public Attack(){
          console.log('40 attack');
      }

      public swim(){
          console.log('swim~~~');
      }
  }

  class Mark44 extends IronMan implements Flyable, Swimable{
      public Attack(){
          console.log('40 attack');
      }

      public fly(){
          console.log('fly higher~~~');	// 성능 업그레이드
      }

      public swim(){
          console.log('swim faster~~~'); // 성능 업그레이드
      }
  }

 

인터페이스 명명할 때 대부분 ~able로 끝나는 것이 많다고 한다. 

인터페이스는 어떤 기능 및 행위를 제공하는데 의미를 강조하기 위해서이다. 

인터페이스를 구현하는 클래스는 어떠어떠한 행위를 할 수 있는 능력을 갖추었단 뜻이기도 하다.

 

마크 2는 걷고 공격하는 기능

마크 36은 나는기능이 추가

마크 40은 수영할 수 있는 기능 추가

마크 44는 다중상속을 통한 두개의 기능 추가 및 성능 업그레이드

 

이렇듯 추상클래스는 이를 상속할 각 자식객체들의 공통점을 추상화 시켜놓은 것! 부모를 타고 올라가면

 

부모클래스가 가진 기능들을 구현해야 할 경우 사용한다.

 

인터페이스는 다른 부모클래스를 가지더라도 특별한 기능이나 행위를 필요할 경우 구현한다.

 

위 나는 기능과 수영기능을 추상클래스 메서드로 넣으면 되지 않느냐? 라고 생각할 수 있지만

위 기능들을 필요로 하지 않는 자식클래스들이 있을 수 있으며 가독성을 해친다.

 

 

정리

 

추상클래스 : is의 관계 부모를 타고 올라가 기능을 완벽히 똑같이 구현해야 할 경우

상속을 받아 기능을 확장한다 (부모의 유전자를 물려받음) 미완성 설계도

 

인터페이스 : 다른 부모클래스를 상속하고 다른 기능이나 행위 추가 구현해야할 모든 클래스에

특정 기능 메서드가 반드시 구현되도록 강제한다.

필요에 따라 인터페이스를 구현할 수 있고 안해도 된다. 다중 상속

 

댓글