Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to have Abstract class in JS?

I have come across prototype inheritance in javascript.

What I wanted to achieve is an outline of methods, which when are inherited must be implemented/defined.

I would like to know if this is possible and if so, how.

like image 432
MostWanted Avatar asked Nov 02 '10 21:11

MostWanted


People also ask

Can we use abstract class in JavaScript?

Abstract classes need to be inherited and require subclasses to provide implementations for the method declared in the abstract class. As in Java, we have the abstract keyword to make a class an abstract class, there are no such reserve keywords in JavaScript to declare a class an abstract class.

Is JavaScript an abstract language?

JavaScript is a weakly typed language and does not have the classical built-in support for abstraction like OOP languages. Instead, JavaScript has the capability to support OOP, and thus can achieve OOP functionalities, which is known as Object Oriented JavaScript (OOJS).


2 Answers

JavaScript really doesn't have anything like this. As you said, JavaScript is prototype-oriented.


As other answers have said, sure, you can simulate this. But I can't see a good reason to do so. Why do object-oriented programmers use interfaces and abstract classes? Astraction and decoupling. These allow you to do all sorts of nice things, like write methods that consume (take as arguments) and produce (return) values that have abstract types - objects that will at least satisfy some contract regarding its methods and fields.

In turn, we get other "nice things" like compile-time checks for type safety. Try to pass an object of type Foo to a method which only accepts objects of type Bar* and you'll get a compiler warning.

And now for the actual explanations

  1. JavaScript will let you pass any object to any function. What you do with that object inside of the function might cause runtime errors - but nothing will stop you from passing arbitrary arguments, even a different number of arguments than the function declares.
  2. JavaScript variables don't have explicit types. What's the point of "guaranteeing" that some object has some set of methods when you still have to perform manual, explicit type checking?
  3. In JavaScript, functions aren't stuck being subservient to objects — they are first class citizens of the language, and can be used just like objects. So? An object's functions can change at runtime. You can add additional functions to an object, or remove them from an object (or shadow a function in the prototype). So, while you can't really change an object's prototype or constructor after creation (read: new), you can change the object's properties.
  4. Similar to point #2, there is no way to guarantee what a function returns, or even guarantee that a function will return any value at all. Functions don't have an explicitly-declared signature in JavaScript in the way that they do in many OO languages.

What are you actually trying to do?

It sounds like you're trying to impose the relative rigidity of strongly-typed, object-oriented languages onto JavaScript's "relaxed, go-with-the-flow" dynamic type system. IMHO, that's not a great idea. Maybe you could explain the actual problem you're trying to solve?

Sorry if this is long-winded, rant-y, or incoherent. I'm sure there's at least one language out there (OCaml?) that totally throws a wrench in my logic. Throw me some feedback.


*Assuming Foo isn't a subtype of Bar, of course.

...but only at runtime, so it's really no more of a guarantee than what you already get with JavaScript's type system.

thus possibly

like image 90
Matt Ball Avatar answered Oct 08 '22 21:10

Matt Ball


Javascript doesn't support it out of the box, but it is easy to simulate the desired semantics. If you have a base 'class' that you want to be abstract, put the method(s) that is (are) abstract on it, and have them throw an error. If the user extends your 'class' and does not provide an implementation, the error will be thrown. For example, you can do

function Thing() {...}
Thing.prototype.abstractMethod = function() {
    throw 'You must implement abstractMethod';
}
like image 43
hvgotcodes Avatar answered Oct 08 '22 21:10

hvgotcodes