prototypejs / prototype

Prototype JavaScript framework
http://prototypejs.org/
Other
3.54k stars 639 forks source link

Multiple class inheritance not working #311

Closed charlesr1971 closed 7 years ago

charlesr1971 commented 8 years ago

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 8 years ago

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

charlesr1971 commented 8 years ago

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 8 years ago

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

charlesr1971 commented 8 years ago

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 8 years ago

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(); 
charlesr1971 commented 8 years ago

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 8 years ago

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

charlesr1971 commented 8 years ago

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 8 years ago

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

charlesr1971 commented 8 years ago

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...

charlesr1971 commented 8 years ago

https://activereload-lighthouse.s3.amazonaws.com/assets/4f51767160e699e591c7f551de2cc212b58fb367/private.b1dd9357a8b08b3e730cc4911cd79a745d22597d.p?AWSAccessKeyId=AKIAJ4QBZRZBVMOUBNZA&Expires=1772756583&Signature=ohmktf7ra7SYh4K9959abd3btzY%3D

fntz commented 8 years ago

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();
charlesr1971 commented 8 years ago

Interesting approach, or:

http://codepen.io/charles1971/pen/bEyBXv

fntz commented 8 years ago

cool :+1:

charlesr1971 commented 8 years ago

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
}
charlesr1971 commented 8 years ago

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 8 years ago

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.

charlesr1971 commented 8 years ago

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...