Расширение и реализация чистого абстрактного класса в 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, мне кажется, что в этом случае "инструменты" были бы более уместными. Но в конце концов они эквивалентны.