Расширение и реализация чистого абстрактного класса в TypeScript

предположим, что у меня есть чистый абстрактный класс (то есть абстрактный класс без какой-либо реализации):

abstract class A {
    abstract m(): void;
}

как в C# и Java, я могу расширения абстрактный класс:

class B extends A {
    m(): void { }
}

но в отличие от в C# и Java я также могу реализовать абстрактный класс:

class C implements A {
    m(): void { }
}

как классы B и C вести себя по-другому? Почему я должен выбирать одно против другого?

(в настоящее время TypeScript справочник и спецификация языка не охватывайте абстрактные классы.)

4 ответов


на осуществляет ключевое слово рассматривает класс A как интерфейс, что означает C должен реализовать все методы, определенные в, независимо от того, есть ли у них реализация или нет в на. Также нет вызовов супер методов в C.

выходит ведет себя больше похоже на то, что вы ожидаете от сайта. Вы должны реализовать только абстрактные методы, и супер звонки/генерируется.

I угадайте, что в случае абстрактных методов это не имеет значения. Но у вас редко бывает класс только с абстрактными методами, если вы это сделаете, было бы намного лучше просто преобразовать его в интерфейс.

вы можете легко увидеть это, глядя на сгенерированный код. Я сделал пример игровой площадки здесь.


дом на @toskv это, если расширения абстрактный класс, вы должны позвонить super() в конструкторе подкласса. Если ты ... --5-->реализовать абстрактный класс, вам не нужно вызывать super() (но вы должны реализовать все методы, объявленные в абстрактном классе, включая частные методы).

реализация абстрактного класса вместо его расширения может быть полезна, если вы хотите создать макет класса для тестирования без беспокоиться о зависимостях и конструкторе исходного класса.


меня привели сюда, потому что я только что задавал себе тот же вопрос, и во время чтения ответов мне пришло в голову, что выбор также повлияет на instanceof оператора.

поскольку абстрактный класс является фактическим значением, которое передается JS, его можно использовать для проверок во время выполнения, когда подкласс расширяет его.

abstract class A {}

class B extends A {}

class C implements A {}

console.log(new B() instanceof A) // true
console.log(new C() instanceof A) // false

в Примере расширений, которые вы даете, вы фактически не добавляете ничего нового в класс. Так оно ничего. Хотя расширение ничем не является допустимым Typescript, мне кажется, что в этом случае "инструменты" были бы более уместными. Но в конце концов они эквивалентны.