TypeScript에서 '확장'과 '구현'의 차이점은 무엇입니까


답변:


153

짧은 버전

  • extends 방법:

새로운 클래스는 아이입니다 . 상속과 함께 오는 이점을 얻습니다. 모든 속성, 메서드가 부모로 있습니다. 이들 중 일부를 재정의하고 새로 구현할 수 있지만 부모 항목은 이미 포함되어 있습니다.

  • implements 방법:

새로운 클래스 로 취급 할 수 같은 "모양" 하면서, 그 아이가 아닌 . Person부모가 다른 것과 상관없이 필요한 모든 메서드에 전달할 수 있습니다.Person

더 ...

에서 OOP (C #, 자바와 같은 언어) 우리가 사용하는 것

extends상속으로 이익을 얻습니다 ( wiki 참조 ). 작은 인용 :

... 대부분의 클래스 기반 객체 지향 언어에서 상속은 하나의 객체가 부모 객체의 모든 속성과 동작을 획득하는 메커니즘입니다. 상속을 통해 프로그래머는 다음을 수행 할 수 있습니다. 기존 클래스를 기반으로하는 클래스 생성 ...

implements다형성에 더 가깝습니다 ( wiki 참조 ). 작은 인용 :

... 다형성은 서로 다른 유형의 엔티티에 대한 단일 인터페이스를 제공하는 것입니다 ...

그래서, 우리는 우리의 class Man.

class Man extends Human ...

그러나 우리가 다른 유형 인 척 할 수 있다고 선언하면- Person:

class Man extends Human 
          implements Person ...

.. Person필요한 곳 어디에서나 사용할 수 있습니다 . 우리는 사람의 사항을 충족해야합니다 "interface" (즉, 모든 공공 물건을 구현) .

implement다른 수업? 정말 멋진 것입니다

자바 스크립트의 멋진 얼굴 (이점 중 하나) 은 덕 타이핑의 내장 지원입니다 ( wiki 참조 ). 작은 인용 :

"오리처럼 걷다가 오리처럼 꽥꽥 거리면 오리 일 것입니다."

그래서, 자바 스크립트, 두 개의 서로 다른 개체 경우 ... 하나 유사한 방법있을 것입니다 (예를 render()) 그들은 그것을 기대하고 함수에 전달 될 수있다 :

function(engine){
  engine.render() // any type implementing render() can be passed
}

그것을 잃지 않기 위해-우리는 Typescript에서 더 많은 유형의 지원으로 똑같이 할 수 있습니다. 그리고 그것이

class implements class

의미가있는 역할이 있습니다.

OOP 언어에서 C#... 할 방법이 없습니다 ...

또한 문서는 여기에 도움이 될 것입니다.

클래스를 확장하는 인터페이스

인터페이스 유형이 클래스 유형을 확장하면 해당 구현이 아닌 클래스의 멤버를 상속합니다. 인터페이스가 구현을 제공하지 않고 클래스의 모든 멤버를 선언 한 것과 같습니다. 인터페이스는 기본 클래스의 개인 및 보호 멤버도 상속합니다. 즉, private 또는 protected 멤버로 클래스를 확장하는 인터페이스를 만들 때 해당 인터페이스 유형은 해당 클래스 또는 하위 클래스에 의해서만 구현 될 수 있습니다.

이것은 큰 상속 계층 구조가 있지만 특정 속성이있는 하위 클래스에서만 코드가 작동하도록 지정하려는 경우에 유용합니다. 하위 클래스는 기본 클래스에서 상속하는 것 외에 관련 될 필요가 없습니다. 예를 들면 :

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {
    select() { }
}

// Error: Property 'state' is missing in type 'Image'.
class Image implements SelectableControl {
    private state: any;
    select() { }
}

class Location {

}

그래서

  • extends 의미-부모로부터 모든 것을 얻습니다.
  • implements이 경우 인터페이스를 구현하는 것과 거의 같습니다. 자식 개체는 부모 인 척할 수 있지만 구현을 얻지 못합니다.

" extends-it gets all from its parent" 라고 말하면 개인 구성원에게 적용됩니까? 예를 들어 class Person {private name: string} class man extends Person{gender: string;}않는 man속성 이름이?
davejoem

개인도 있습니다. TS에서 액세스 할 수 없습니다. 그들을 보호하고 사용할 수 있습니다. "구현"의 경우 공개 부분 만 의미가 있습니다. 희망이 조금 도움이
Radim 쾰러에게

훌륭한 대답입니다. "개인은 있지만 TS에서 액세스 할 수 없음"에 대한 귀하의 의견으로 확실하지 않습니다. 새로 만든 자식 개체에 개인 속성이 복사된다는 뜻입니까? 그리고 구현의 경우 공용 속성 만 복사됩니까?
kushalvm

또한 한 점 더 있습니다. 이것이 확장의 정의라면. 그렇다면이 stackoverflow.com/questions/60390454/…를
kushalvm

96

타이프 스크립트 (및 기타 OO 언어)에는 클래스와 인터페이스가 있습니다.

인터페이스에는 구현이 없으며이 유형의 멤버 / 메서드에 대한 "계약"일뿐입니다.
예를 들면 :

interface Point {
    x: number;
    y: number;
    distance(other: Point): number;
}

이 구현 인스턴스 Point: 인터페이스 유형 번호의 두 멤버가 있어야 x하고 y, 하나의 방법은 distance다른 수신 Point인스턴스를하고를 반환합니다 number.
인터페이스는 이들 중 어느 것도 구현하지 않습니다.

클래스는 구현입니다.

class PointImplementation implements Point {
    public x: number;
    public y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    public distance(other: Point): number {
        return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
    }
}

( 놀이터의 코드 )

귀하의 예제에서는 Person클래스를 확장 할 때 한 번 클래스로 취급 하고 구현할 때 한 번은 인터페이스로 취급합니다.
코드 :

class Person {
    name: string;
    age: number;
}
class Child  extends Person {}

class Man implements Person {}

다음과 같은 컴파일 오류가 있습니다.

'Man'클래스가 'Person'인터페이스를 잘못 구현합니다.
'Man'유형에 'name'속성이 없습니다.

인터페이스가 구현되지 않았기 때문입니다.
따라서 implement클래스 인 경우 구현없이 "계약"만 가져 오므로 다음을 수행해야합니다.

class NoErrorMan implements Person {
    name: string;
    age: number;
}

( 놀이터의 코드 )

결론은 대부분의 경우 extend다른 클래스가 아닌 다른 클래스 를 원한다는 implement것입니다.


7
이 대답은 이해하기 더 쉽습니다.
Akshay Raut

6

@ nitzan-tomer의 훌륭한 답변! 저를 많이 도왔습니다 ... 저는 그의 데모를 다음과 같이 약간 확장했습니다.

IPoint interface;
Point implements IPoint;
Point3D extends Point;

그리고 IPoint유형을 기대하는 함수에서 어떻게 작동하는지 .

그래서 내가 지금까지 배웠고 엄지 규칙으로 사용하고있는 것은 : 제네릭 유형을 기대하는 클래스와 메서드를 사용하는 경우 인터페이스를 예상 유형으로 사용하십시오. 그리고 부모 또는 기본 클래스가 해당 인터페이스를 사용하는지 확인하십시오. 이렇게하면 인터페이스를 구현하는 한 모든 하위 클래스를 사용할 수 있습니다.

여기에 확장 된 데모


이것은 질문에 대한 답을 제공하지 않습니다. 작성자에게 비판이나 설명을 요청하려면 게시물 아래에 댓글을 남겨주세요. - 리뷰에서
aronisstav

1
@aronisstav 나는 이미 나를 도왔던 좋은 대답을 찾은 것에 대한 확장 데모 만 게시했습니다. 하지만 다른 사람이 내가 데모를 확장 한 작업이 유용하다고 생각할 수도 있습니다. 그게 다야. 주석은 실제로 코드 블록을 넣는 것을 의미하지 않으므로 답변 포스트에서 더 잘 이해할 수 있습니다. 그래서 그것의 문제는 무엇입니까?
andzep

귀하의 답변은 길이와 내용으로 인해 (자동으로?) 신고되었고, 내 리뷰 대기열에 표시되었으며, 신고에 표시된 이유에 대한 장점을주었습니다. 주요 기여 (데모를 확장했다는 설명)는 주석으로 더 좋을 것입니다. 추가 된 단락으로 아마도 실제로 더 유용 할 것입니다.
aronisstav

@andzep 확장 데모 예제는 정말 도움이됩니다.
namit

3
  1. 인터페이스는 모양으로 인터페이스를 확장합니다.
  2. 인터페이스는 모양으로 클래스를 확장합니다.
  3. 클래스 구현 인터페이스는 인터페이스에서 제공하는 모든 필드를 구현해야합니다.
  4. 클래스는 모양으로 클래스를 구현합니다.
  5. 클래스는 모든 필드로 클래스를 확장합니다.

extends상속에 implements초점을 맞추고 인터페이스 든 클래스 든 제약에 초점을 맞 춥니 다.


0

VS 구현 확장

  • extends: 자식 클래스 (확장 됨)는 클래스의 모든 속성과 메서드를 상속 합니다.
  • implements: implements키워드 를 사용하는 클래스는 키워드 를 사용하는 클래스의 모든 속성과 메서드 를 구현 해야 합니다.implements

더 간단하게 말하면 :

  • extends: 여기에서 부모 클래스에서 이러한 모든 메서드 / 속성을 가져 오므로 직접 구현할 필요가 없습니다.
  • implements: 여기에 수업이 따라야 할 계약이 있습니다. 클래스는 최소한 다음 메소드 / 속성 을 구현 해야합니다.

예:

class Person {
  name: string;
  age: number;

  walk(): void {
    console.log('Walking (person Class)')
  }

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
class child extends Person { }

// Man has to implements at least all the properties
// and methods of the Person class
class man implements Person {
  name: string;
  age: number

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

  walk(): void {
    console.log('Walking (man class)')
  }

}

(new child('Mike', 12)).walk();
// logs: Walking(person Class)

(new man('Tom', 12)).walk();
// logs: Walking(man class)

예제에서 우리는 자식 클래스가 Person으로부터 모든 것을 상속받는 반면, man 클래스는 Person 자체에서 모든 것을 구현해야한다는 것을 관찰 할 수 있습니다.

예를 들어 walk 메소드와 같이 man 클래스에서 무언가를 제거하면 다음과 같은 컴파일 시간 오류가 발생합니다.

'man'클래스가 'Person'클래스를 잘못 구현합니다. 'Person'을 확장하고 그 구성원을 하위 클래스로 상속하려고 했습니까? 'man'유형에는 'walk'속성이 없지만 'Person'유형에는 필수입니다. (2720)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.