Структурная типизация и полиморфизм - добавление супертипов - PullRequest
0 голосов
/ 29 апреля 2018

Ниже приведен пример кода (полиморфный), взятый из угловой каркас с использованием синтаксиса TypeScript,

export abstract class AbstractControlDirective {
   ...
}

AbstractControlDirective подтипы

export abstract class NgControl extends AbstractControlDirective {
     ...
}
export abstract class ControlContainer extends AbstractControlDirective {
   ...
}
export declare abstract class ControlContainer extends AbstractControlDirective {
  ...
}
export declare abstract class NgControl extends AbstractControlDirective {
    ...
}

NgControl подтипы

export class NgModel extends NgControl implements OnChanges, OnDestroy {
   ...
}

export class FormControlDirective extends NgControl implements OnChanges {
    ....
}

export class FormControlName extends NgControl implements OnChanges, OnDestroy {
   ...
}

export declare class FormControlDirective extends NgControl implements OnChanges {
    ...
}

export declare class FormControlName extends NgControl implements OnChanges, OnDestroy {
   ...
}

export declare class NgModel extends NgControl implements OnChanges, OnDestroy {
   ...
}

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


Чтобы избежать этой проблемы, можем ли мы поддерживать эту иерархию без использования ключевого слова extends? TypeScript является структурно типизированным ...

1 Ответ

0 голосов
/ 29 апреля 2018

Класс должен наследовать от родителя (ключевое слово extends в классах ES6), если выполняется одно или несколько следующих условий:

  • родительский класс имеет явный конструктор, который должен наследоваться в дочернем классе, включая поля класса и свойства параметров конструктора (которые являются синтаксическим сахаром для тела конструктора класса ES6).

  • родительский класс имеет конкретные элементы-прототипы (методы и методы получения / установки), которые должны присутствовать в дочернем классе

  • экземпляры дочернего класса должны быть идентифицируемы как экземпляры родительского класса во время выполнения с child instanceof Parent

  • родительский класс имеет декораторы, которые влияют на что-либо из вышеперечисленного

В противном случае наследование не дает никаких преимуществ и приводит к чрезмерной цепочке прототипов; дочерний класс может просто реализовать родительский интерфейс (implements ключевое слово).

AbstractControlDirective содержит конкретные элементы, которые должны наследоваться в дочерних классах, поэтому NgControl расширяет его:

export abstract class NgControl extends AbstractControlDirective {...}

HttpXsrfTokenExtractor содержит только абстрактные элементы, поэтому HttpXsrfCookieExtractor не нужно расширять его, а просто реализует как интерфейс:

export class HttpXsrfCookieExtractor implements HttpXsrfTokenExtractor {...}
...