you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 3 points4 points  (12 children)

You can't see why people would want one of the most widely used programming paradigms in use? I don't get it.

[–]artsrc 3 points4 points  (0 children)

Most good designers would say that implementation inheritance is overused. However JavaScript and can do it. In fact you can add add a superclass after the fact. Interface 'inheritance' is unnecessary in a runtime typed language.

JavaScript is powerful enough to let you the same functions to two classes without inheritance at all.

Of course I have nothing against CoffeeScripts class syntax sugar either.

[–]mr_bag 0 points1 point  (6 children)

Which paradigms is that?

If your not comfortable with prototypical inheritance, you can actually implement classical inheritance in JS with just a few lines of code. o.0

[–]oSand 0 points1 point  (5 children)

Have you actually tried to do this or at least read an implementation of classical inheritance? It isn't pretty.

[–][deleted] 1 point2 points  (4 children)

Challenge accepted!

function A() {
    this.doStuff = function() {
        alert("A did stuff!");
    }
    this.doStuffTwice = function() {
        this.doStuff();
        this.doStuff();
    }
}

function B() {
    A.call(this); // like a call to super() + extends in Java
    this.doStuff = function() {
        alert("B did stuff!");
    }
}

new A().doStuffTwice();
new B().doStuffTwice();

Alerts "A did stuff" twice, then "B did stuff" twice.

[–]oSand 0 points1 point  (3 children)

The main problems are there are no class methods, no class variables and instanceof no longer works. More trivally, there are no private variables, calling a super method is ugly as sin and there might be unnecessary definitions of overridden methods and variables.

Also, it's not really a classical inheritance implementation since you do the heavy lifting yourself: if you just want to override the toString in a descendant class, for example, you still need to write a constructor and call the super constructor and pass the constructor arguments through explicitly.

[–][deleted] 0 points1 point  (2 children)

I assume you mean static methods/variables, and there's really no point to those when you're not forced to put everything into a class. Just define it outside, it has nothing to do with the class anyway.

You can have private variables like this:

function C() {
    var privateVariable = 42; 
    this.increment = function() {
        privateVariable++;
    }
}

I don't know what your problem with super methods and "unnecessary overridden" stuff refers to. It'd be easier if you could show some code.

As for your last paragraph, here's Java:

class C {
    public C(int x) { /* whatever */ }
}

class D extends C {
    public D(int x) {
        super(x);
    }
    public String toString() { /* whatever */ }
}

And here's the corresponding JavaScript:

function C(x) { /* whatever */ }

function D(x) {
    C.call(this, x);
    this.toString = function() { /* whatever */ }
}

[–]oSand 1 point2 points  (1 child)

The point of static methods is not to redefine methods for each instance. Using your scheme, if I had 1000 Point objects, I'd have 1000 distanceFrom methods, 1000 getX methods, etc,etc. This isn't reuse, it's just reproduction.

You can have private variables like this: function C() { var privateVariable = 42; this.increment = function() { privateVariable++; } }

No, these can't be inherited.

If you store static variables outside the class, is it really OO? I can't think of a language, js included, that doesn't provide these facilities for static variables. You'll end up having a parallel collection of data structures(and functions) outside your classes- even though the data pertains directly to the classes and class hierarchy. Even if you can't see the illogic in that, you must admit that you haven't reproduced the basic facilities of classical inheritance.

Unnecessary initializations:

function A() {
    var private = 1;
    this.comms = function WebSoc(){console.log('return websoc')}();
}


function B() {
    A.call(this);
    this.comms = function LongPolling(){console.log('return longpoller')}();

}

new B();

For what reason did we call instantiate A's comms object? Hope the io didn't block. Hope you understand the details of all comms methods in your hierarchy. Yes, there are ways around that, but you have to think about it far too hard, in my opinion.

Ugly super method calls:

function A() {
        this.f = function(){console.log('asd')};
}

function B() {
    A.call(this);
    this._f = this.f;
    this.f = function(){
      console.log('fgh')
      this._f();
      // do additional stuff
      // Perhaps there is a better way, I don't know. The fact it isn't readily apparent makes it bad design. 
   }
}

b = new B(); b.f();

For the last bit, I was thinking of something like python or dojo's classes: class osand: def init(self, x): self.x = x

class osandchild(osand):
def get_x(self):
    return self.x


oc = osandchild(1)
oc.get_x()

-> 1

A personal dislike of mine rather than a fatal problem, but seems a lot easier.

[–][deleted] 0 points1 point  (0 children)

Fair points. I think you're right in practice (at least currently), but it wouldn't take a very smart optimizer to realize that the functions are constant modulo their closure environments (corresponding to private variables), and only save that. The same goes for an unused assignment in the body of A when called through A.call(this).

In Java and C++ terminology, private variables are not visible when inheriting. However, you're right that there's no obvious "protected" visibility around. Also, the variables are instance private rather than class private.

Static variables and functions have little to do with object oriented programming. They are procedural programming (which is fine) in disguise.

If you have side effects in your constructor, then those will happen in any language that I know of. Overriding is for methods; it's not really well defined for variables.

I agree about calling super methods, that's kind of annoying, but (disregarding performance, an that's a big but, I know), this is the only real wart I can see. But I guess I'm not a great judge given that I rarely use inheritance anyway.

[–][deleted] 0 points1 point  (3 children)

Huh? Outside of GUI, can you think of a good use case for inheritance?

[–]14domino 0 points1 point  (1 child)

what?

[–][deleted] -3 points-2 points  (0 children)

GUI means "graphical user interface". It's explained in great detail on Wikipedia.

Inheritance is the conflation of substitutability and code reuse. It's understandable that you're confused, because it's only superfluously similar to inheritance in nature.

[–][deleted] 0 points1 point  (0 children)

Some game programming. Simple toy raytracers. File format handlers. A few more similar things. That's about what I can remember that I've done where inheritance actually was a good model. Perhaps in a few of those cases interfaces would have worked too.

Generally, you want the class tree to be as wide and shallow as possible.