Можно ли иметь абстрактный класс в JS? - PullRequest
14 голосов
/ 03 ноября 2010

Я сталкивался с наследованием прототипа в javascript.

То, чего я хотел достичь, - это описание методов, которые при наследовании должны быть реализованы / определены.

Я хотел бы знать, возможно ли это, и если да, то как.

Ответы [ 2 ]

25 голосов
/ 03 ноября 2010

JavaScript действительно не имеет ничего подобного.Как вы сказали, JavaScript ориентирован на прототип .


Как уже говорили другие ответы, конечно, вы можете смоделировать это.Но я не вижу веских причин для этого.Почему объектно-ориентированные программисты используют интерфейсы и абстрактные классы? Astraction и развязка .Это позволяет вам делать всякие приятные вещи, такие как методы записи, которые принимают (принимают в качестве аргументов) и производят (возвращают) значения, имеющие абстрактные типы - объекты, которые будут по крайней мере удовлетворять некоторому договору относительно его методов иfields.

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

А теперь для фактических объяснений

  1. JavaScript позволит вам передать любой объект любой функции.То, что вы делаете с этим объектом внутри функции, может привести к ошибкам во время выполнения - но ничто не помешает вам передавать произвольные аргументы, даже если количество аргументов отличается от того, которое объявляет функция.
  2. Переменные JavaScriptне имеют явных типов.Какой смысл «гарантировать» , что у некоторого объекта есть некоторый набор методов, когда вам все еще приходится выполнять ручную, явную проверку типов?
  3. В JavaScript функции не застряли, будучи подчиненнымик объектам - они являются первоклассными гражданами языка и могут использоваться как объекты.Так? Функции объекта могут изменить во время выполнения . Вы можете добавить дополнительные функции к объекту или удалить их из объекта (или скрыть функцию в прототипе).Таким образом, хотя вы не можете реально изменить prototype или constructor объекта после создания (читай: new), вы можете изменить свойства объекта.
  4. Как и в пункте № 2, нетспособ гарантировать, что функция возвращает, или даже гарантировать, что функция вернет любое значение вообще.Функции не имеют явно объявленной подписи в JavaScript, как во многих языках ОО.

Что вы на самом деле пытаетесь сделать?

Звучит как вымы пытаемся навязать относительную жесткость строго типизированных объектно-ориентированных языков к динамической системе типов JavaScript "relaxed, go-with-the-flow".ИМХО, это не очень хорошая идея.Может быть, вы могли бы объяснить реальную проблему, которую вы пытаетесь решить?

Извините, если это многословно, бессмысленно или бессвязно.Я уверен, что есть хотя бы один язык ( OCaml? ), который полностью нарушает мою логику.Дайте мне некоторую обратную связь.


* Предполагая, что Foo, конечно, не подтип Bar.

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

, таким образом, возможно

9 голосов
/ 03 ноября 2010

Javascript не поддерживает его «из коробки», но легко смоделировать желаемую семантику.Если у вас есть базовый «класс», который вы хотите быть абстрактным, поместите в него методы, которые являются абстрактными, и пусть они выдают ошибку.Если пользователь расширяет ваш «класс» и не предоставляет реализацию, будет выдана ошибка.Например, вы можете сделать

function Thing() {...}
Thing.prototype.abstractMethod = function() {
    throw 'You must implement abstractMethod';
}
...