prototypejs/prototype

Multiple class inheritance not working

charlesr1971 opened this issue · 18 comments

var someclassname = Create.class(baseclass1,baseclass2,{
})

This does not inherit both base classes. Multiple inheritance is a cornerstone of any OO framework.
Please could we update this feature to include multiple inheritance.

Thanks

Charlie

fntz commented

try

var A = Class.create({
  foo: function() {
    alert("A#foo");
  }
});
var B = {
  bar: function() { alert("B#bar"); }
};
var C = Class.create(A, B, {
  baz: function($super) {
    alert("C#baz");
  }
});
var c = new C();
c.baz();
c.foo();
c.bar(); 

As first argument pass a superclass (A in this case), and next argument it's a javascript object with method, or use addMethods

Thanks Fntz, but surely, if I can add a superclass & an object, I should be able to add more than one superclass. Why the restriction? At the moment I have single line ancestry.

fntz commented

for my opinion multiple inheritance is not always good, but inheritance via traits (or objects in javascript) make sence

But, it is a hallmark of many classical OO languages. For instance, in your example, I cannot use the $super keyword for methods in the object [argument 2]...

fntz commented

Use the next trick

var A = Class.create({
  foo: function() {
    alert("A#foo");
  }

});
var B = {
  bar1: function() { alert("B#bar1"); }
};

A.addMethods(B);  // <- extend A class

var C = Class.create(A, {
  bar1: function($super) {
    alert("C#baz");
    $super();
  }
});
var c = new C();
c.bar1(); 

So, in terms of building a framework. I could do the following:

var modal.package = Class.create({
});

var layout = {
width: function() {...},
height: function() {...}
};

var move = {
tocenter: function(){....}
};

modal.package.addMethods(layout);
modal.package.addMethods(move);

var modal = Class.create(modal.package, {
create: function() {
use inherited methods to create
modal window
}
});

So the pattern is, to have one base class package for each related subclass. The base class package consists of a number of mix ins. I can then use a combination of these mix in objects to create new base class packages for different subclasses.

fntz commented

Yes, of course, a long time ago, i worked on own widgets implementation, where i used a prototype.js. I can see sources in repo

Wow. Thanks fntz. You have solved my conundrum, in relation to prototype.js & OO. By the way, I really like using prototype.js. More than jQuery...

fntz commented

you are welcome :)
prototype.js it's the best javascript library

I like your widgets. Very clean implementations. I basically use prototype.js classes all the time now & I can now make them even more modular, using this design pattern. I am a little disappointed that the $private keyword patch was not implemented. So I am having to resort to the closure method around the class return...

fntz commented

You might use the next trick for private methods:

var A = function() {
  var private_method = function() {
    alert("private");
  };
  var _A = Class.create({
     call_private: function() {
       private_method();       
     }
  });
  return new _A();
};

var a = new A();
a.call_private();
fntz commented

cool 👍

So, further to our discussion this morning, I have come up with the following framework:

---- framework.base.js ----

// namespace
var framework = {};
// namespace alias
var $f = framework;
// heirarchy
framework.base = {};
framework.object = {};
framework.modal = {};

---- framework.object.callback.js ----

framework.object.callback = {
...callback functions
}

---- framework.object.element.js ----

framework.object.element = {
...element functions
}

---- framework.object.events.js ----

framework.object.events = {
...events functions
}

---- framework.object.layout.js ----

framework.object.layout = {
...layout functions
}

---- framework.object.move.js ----

framework.object.move = {
...move functions
}

---- framework.base.modal.js ----

framework.base.modal = Class.create ({
});
framework.base.modal.addMethods(framework.object.callback);
framework.base.modal.addMethods(framework.object.element);
framework.base.modal.addMethods(framework.object.events);
framework.base.modal.addMethods(framework.object.layout);
framework.base.modal.addMethods(framework.object.move);

---- framework.modal.view.js ----

framework.modal.view = Class.create (framework.base.modal, {
...modal view functions
}

---- framework.modal.notification.js ----

framework.modal.notification = Class.create (framework.base.modal, {
...modal notification functions
}

Actually, Mike. I am now using ds.oop. It works brilliantly with prototype.js and supports, private, public variables, multiple inheritance, overloading and pretty much everything you would expect from a traditional OO language. I converted the above framework in 5 minutes to ds.oop, which uses almost identical syntax:

http://digital-synapse.github.io/ds.oop/
https://github.com/digital-synapse/ds.oop

Example:

https://github.com/digital-synapse/ds.oop-inheritancetest/blob/master/index.js

fntz commented

Looks good, by some notes some of the words which used in library are reserved in javascript http://www.javascripter.net/faq/reserved.htm

I use a coffeescript but coffee does not have private, protected variables/methods.

Yes. Mike. The author explains this in a footnote [at the bottom of the page]:

https://github.com/digital-synapse/ds.oop/wiki/Getting-Started

Apparently, it is easy to change the references to these reserved words...