it공부 (개념)/javascript

abstract Modifier(추상 제어자)란? 개념 및 Typescript예제

cantor 2023. 2. 12. 00:00

abstract 키워드는 "틀"을 만드는데 사용된다.

abstract?

    • 타입스크립트의 abstract 제어자:
      클래스 및 메서드선언에 사용된다.
      선언한 요소의 직접적인 사용을 막는 제어자이다.

      abstract로 선언된 객체들은 기존 기능의 직접사용이 불가능해지고, 
      그것들을 상속받는 객체들을 위한 청사진 역할만 수행할 수 있게 된다.

      객체지향의 핵심 특징 중 "추상화"와 "상속"을 구현하는 역할을 한다.

 

    • 사전적 의미:
      구체적인 형태나 성질을 갖고 있지 않은,
      일반적인, 포괄적인

      abstract 제어자로 선언된 클래스는 인스턴스 생성이 불가능하며,
      abstract 메서드는 다른 클래스에 상속 전에는 사용은커녕 기능의 정의조차 불가능하다.

      즉, 상속받는 여러 클래스들의 일반적인 특징(메서드의 이름, 호출 시그니처등)
      만 갖고 있으며, 상속 전에는 구체적으로 구현되어있지 않다.

 

 

 

1. abstract 클래스

//abstract 클래스
//메서드는 abstract 키워드가 없이 정의할시 일반메서드가 된다.

abstract class AbsClass {
    normalMethod():void {
        console.log("abstract class can have normal method")
    }
}

 

-다른 클래스가 상속받는 용도로만 사용되는 클래스.

-인스턴스를 생성할 수 없다.

 

2. abstract 메서드

abstract class AbsClass {
    
    //abstract 메서드
    
    abstract absMethod(): void;
    
    }

 

 

-abstract 클래스 내부에서만 선언이 가능하며,

선언된 곳에서는 implementation(동작 및 기능)을 정의할 수 없다.

 

-abstract 클래스를 상속받는 클래스에서 반드시 정의되어야 하며,

서브 클래스 내부에서 실제 동작 및 기능을 정의한다.

 

 

타입스크립트 예제

예제코드: abstract클래스를 상속받는 클래스

//abstract 클래스
abstract class AbsClass {

    //abstract 메서드
    abstract absMethod (): void;

}


// abstract 클래스를 상속받는 클래스
// "extends" 키워드를 사용한다
class subClass extends AbsClass{
    
    // 상속된 abstract 메서드의 기능 정의
    // 별다른 키워드가 필요없다.
    // 그냥 override를 해주면된다.
    
    absMethod(): void {
        console.log("defined")
    }

}

.

 

abstract는 타입스크립트의 추가문법이다.

자바스크립트에는 포함되어있지 않다.

// 위의 코드를 컴파일한 자바스크립트 코드


// abstract 제어자가 전부 사라졌다.
class AbsClass {
}
class subClass extends AbsClass {
    absMethod() {
        console.log("defined");
    }
}

 

 

abstract 제어자는 사용 가능한 위치가 엄격히 정해져 있다.

잘못 사용할 시 다양한 오류가 발생한다.

4가지 오류

 

 

오류해설이 적힌 예제코드

abstract class AbsClass {

    abstract absMethod (): void;
    
    //오류 1.
    //abstract 메서드는 실행부분이 정의되어선 안된다.
    abstract absMethod2 () {
        console.log("undefined")
    }

}
//오류 2.
//abstract class로 인스턴스를 생성할 수 없다.

const instance = new AbsClass();


//abstract 메서드를 상속받는 클래스

class subClass extends AbsClass{
    //오류 3.
    //AbsClass의 abstract메서드 "absMethod"가 정의되자 않았다. 
    
    //오류 4. abstract 메서드는 abstract 클래스에서만 선언이 가능하다.
    abstract absMethod2(): void;

}

 

 

 

 

 

abstract 제어자를 사용하는 이유

 

 

1. 특정 기능 혹은 기능의 이름을 공유하는 다양한 클래스를 만들기 편하다.

 

클래스 끼리는상속을 통한 기존코드 이어받기 새로운 기능을 확장하기가 편하다.

 

abstract 클래스는 일반 메서드 및 abstract 메서드, 그리고 변수정의로

완전한 기능은 갖고 있지 않은 기본적인  클래스 전용 "틀"을 제공해 준다.

 

즉 같은 특성을 공유하지만 미묘하게 다른 기능을 갖는 여러 클래스들의 청사진이 될 수 있다.

 

타입스크립트 예제


abstract class Animal {

    // abstract 메서드 
    // Animal을 상속받는 서브클래스별로 
    // 다른기능을 갖는다.
    
    abstract fastmove ():void;
    
    // 일반메서드
    // 서브클래스에서 모두 같은기능을 갖는다
    
    drink () {
    console.log("drink water")
    }
}

// Animal을 상속받는 eagle
class eagle extends Animal {
    fastmove() {
        console.log("flying")
    }
}

// Animal을 상속받는 tiger
class tiger extends Animal {
    fastmove(): void {
        console.log("running")
    }
}

 

 

 

 

2. interface에 비해 유용하다.

 

 

 

 

interface(인터페이스) 개념 및 Typescript 예제

타입스크립트 소개 및 개발 준비 게시물의 링크는 이 글의 맨 밑에 있습니다. Art and design icons created by Freepik - Flaticon 목차. A. interface의 개념 사전적 정의, 프로그래밍 언어에서의 정의 사용이유 B

batcave.tistory.com

사실 interface도 클래스의 기본적인 틀을 제공할 수 있다.

또 상속받은 클래스가 새로운 기능을 추가하여 확장하는 것도 편하다.

게다가 "서브 클래스가 반드시 정의해야 하는 메서드"를 지정해 주는 기능도 물론 있다.

 

// interface에서는  abstract키워드없이 추상메서드를 정의할 수 있다.
// 하지만 일반메서드를 정의할수없다.

interface Animal {
    fastmove(): void;
}

class eagle implements Animal{
    fastmove(): void {
        console.log("flying")
    }
}

class tiger implements Animal{
    fastmove(): void{
        console.log("running")
    }

}

 

 

하지만 interface에는 치명적인 단점이 있다.

바로 일반 메서드를 정의할 수 없다는 점이다.

 

그래서 여러 가지 클래스의 특성과 공통된 메서드를 갖는 클래스만의 "청사진" 역할에는 

abstract 가 interface보다 더 유용하다.

 

interface는 단순히 가져야 하는 구성요소의 목록을 나열하는 데에 특화된 기능이므로,

"클래스전용 틀"에는 좀 더 부적합하다.

 

 

 

 

읽어주셔서 감사합니다.

 

오탈자나 오류가 있을 경우 댓글로 알려주세요.