Useful classical inheritance example?

O

optimistx

There are numerous examples about trying to implement classical inheritance
in javascript. Most authors seem to take for granted that classical
inheritance or simulating it is necessary in any language, incl javascript.

I am ashamed to confess that in spite of about 15 years of using object
oriented languages in my hobbies I am not really convinced about the
usefulness of inheriting. May be that if somebody makes a set of programs
for others to inherit from the idea might be practical. Is it so that
inheritance is needed and useful in big projects, with tens or hundreds of
people coding? But designing class inheritance is waste of energy when
writing some internet pages alone or together with some friends?

The educational examples are about animals, cats and dogs, or persons
becoming employees and managers, or shapes on the screen becoming
rectangles, circles, or vehicles becoming cars and sports cars. But
something bothers me all the time with these examples: why not make those
objects directly without wrestling with inheritance code like

function extend(B, A) {

Intermediate = function (){};
Intermediate.prototype = A.prototype;
B.prototype = new Intermediate();
B.prototype.constructor = B;
B.parentConstructor = A;
}

I would like to see a simple and useful example about classical inheritance
in any language. Convince myself that inheritance there saves from writing
repeated code or helps in maintaining or understanding the situation. After
that I would try to see, how that example could be written in prototypal
language javascript, with simulated classical inheritance or using the
natural features of prototypal language.

When it is possible to add, delete, replace methods and other properties in
the objects using constructor functions simply to do that, why wrestle with
mysterious and astounding features in 'inheritance'? Is the reason simply
that programmers have learnt that inheritance in C++, Java etc must be good
for their health (although they might not be se sure about that: eat more
sallad, I'll eat...).

Peter Michaux has presented an example about subject-observer patterns and
showed some variants to solve that in 'javascript-way' instead of classical
(?) .

http://peter.michaux.ca/articles/transitioning-from-java-classes-to-javascript-prototypes

There are some astounding sentences/references there like 'Java classes are
a mistake ' (or something like that).

I have to play and learn about this example. In the meantime, can you give
links to examples which have convinced you about the usefulness of classical
inheritance?
 
A

abozhilov

Hi optimistx.
function extend(B, A) {

Intermediate = function (){};
Intermediate.prototype = A.prototype;
B.prototype = new Intermediate();
B.prototype.constructor = B;
B.parentConstructor = A;

}

I know, this is only for example, but:

extend is reserved word from JavaScript. See:
7.5.3 Future Reserved Words in ECMA 3
In someone of the future version, that code will be produce error.

Intermediate in this case, will be defined in scope of `Global
Object`.

B.parentConstructor = A;
I'm confused from that line. What is advantage of this approach?
B is instance from Function object. B have implicit reference to
Function.prototype, Function.prototype have implicit reference to
Object.prototype.
So B.parentConstructor is: function Object(){}.

At the moment i don't see where to use parentConstructor. And what is
advantage of this? Maybe more readeable code? I don't thing so.

Sorry if my post gone to off topic.
 
T

-TNO-

There are numerous examples about trying to implement classical inheritance
in javascript. Most authors seem to take for granted that classical
inheritance or simulating it is necessary in any language, incl javascript.

classical inheritance, no. Inheritance in general? Maybe.

I am ashamed to confess that in spite of about 15 years of using object
oriented languages in my hobbies I am not really convinced about the
usefulness of inheriting.

I've heard it said by an academician that if you squint hard enough,
inheritance
violates encapsulation. I'm not sure what I think of that though, but
at least
you're not alone in your thoughts.

May be that if somebody makes a set of programs
for others to inherit from the idea might be practical.  Is it so that
inheritance is needed and useful in big projects, with tens or hundreds of
people coding? But designing class inheritance is waste of energy when
writing some internet pages alone or together with some friends?

Proper use of prototypical inheritance can and will save you coding
time and
significant memory (code re-use, and no member copying).
The educational examples are about animals, cats and dogs, or persons
becoming employees and managers, or shapes on the screen becoming
rectangles, circles, or vehicles becoming cars and sports cars. But
something bothers me all the time with these examples: why not make those
objects directly without wrestling with  inheritance code ...

Many examples and tutorials are convulated due to misguided
understanding
of the problem IMO. Understanding the relationships between the
elements of
your system are fundamental to building code that isn't a self-hosted
hack
into something "good-enough"
I would like to see a simple and useful example about classical inheritance
in any language. Convince myself that inheritance there saves from writing
repeated code or helps in maintaining or understanding the situation. After
that I would try to see, how that example could be written in prototypal
language javascript, with simulated classical inheritance or using the
natural features of prototypal language.

You don't need side by side examples of different languages to
understand
code abstraction. Why would you ever want to copy and paste identical
code definitions
over and over for multiple objects? Verbose code does not
automatically mean readable code.

When it is possible to add, delete, replace methods and other properties in
the objects using constructor functions simply to do that, why wrestle with
mysterious and astounding features in 'inheritance'?

I don't think you properly understand what a constructor does.
 
T

-TNO-

classical inheritance, no. Inheritance in general? Maybe.


I've heard it said by an academician that if you squint hard enough,
inheritance
violates encapsulation. I'm not sure what I think of that though, but
at least
you're not alone in your thoughts.


Proper use of prototypical inheritance can and will save you coding
time and
significant memory (code re-use, and no member copying).


Many examples and tutorials are convulated due to misguided
understanding
of the problem IMO. Understanding the relationships between the
elements of
your system are fundamental to building code that isn't a self-hosted
hack
into something "good-enough"


You don't need side by side examples of different languages to
understand
code abstraction. Why would you ever want to copy and paste identical
code definitions
over and over for multiple objects? Verbose code does not
automatically mean readable code.


I don't think you properly understand what a constructor does.

Apologies for bad formatting.
 
J

John G Harris

I would like to see a simple and useful example about classical
inheritance in any language. Convince myself that inheritance there
saves from writing repeated code or helps in maintaining or
understanding the situation. After that I would try to see, how that
example could be written in prototypal language javascript, with
simulated classical inheritance or using the natural features of
prototypal language.
<snip>

Look no further than the javascript DOM 1 spec if you want a realistic
example :
<http://www.w3.org/TR/REC-DOM-Level-1/>
see the ECMAScript appendix.

There you'll see that HTMLElement objects have all the methods and data
properties of Element objects, which in turn have all the methods and
data properties of Node objects.

John
 
T

Thomas 'PointedEars' Lahn

abozhilov said:
I know, this is only for example, but:

extend is reserved word from JavaScript. See:
7.5.3 Future Reserved Words in ECMA 3

The correct caption of the section in all Editions is

| 7.5.3 Future Reserved Words

(Of course, ECMA/Ecma International would not have written obvious nonsense
like "ECMA 3" as the Editions of the ECMAScript Language Specification are
registered under ECMA-262.)
In someone of the future version, that code will be produce error.

If you would have read more carefully, you would have noticed that the
future reserved word is spelled `extends' (like in Java, from which it is
most certainly taken).

JFYI: I am using a similar approach, but I am augmenting the object referred
to by Function.prototype with an extend() method instead. This has the
advantage of not "spoiling the global namespace", being callable as method
of Function instances, and as it returns a Function instance, can be used in
an assignment expression. It leads to compact, but (IMHO) still readable
code like

/**
* @param s
* @extends jsx.Error
*/
jsx.object.ObjectError = (
function(s) {
arguments.callee._super.call(this, s);
}
).extend(jsx.Error, {
name: "jsx.object.ObjectError"
});
Intermediate in this case, will be defined in scope of `Global
Object`.

No. Learn to distinguish between property, execution context and scope. An
object does not have (a) scope (chain); that is only associated with an
execution context. You probably mean instead that the `Intermediate'
identifier will (probably, since we do not know where this code is going to
be used) be implicitly defined in the global execution context, as a
property of the Global Object; know that is not a Bad Thing per se.
B.parentConstructor = A;
I'm confused from that line. What is advantage of this approach?

It is syntactic sugar so that B instances know that they inherit from
A.prototype; this is particularly useful if a constructor calls the "parent"
constructor to set properties. In class-based inheritance this is (AFAIK)
used for initialization only; in emulated class-based inheritance in a
dynamic prototype-based language this can also be used to *create*
properties for a certain "class" of objects when they are constructed.
B is instance from Function object.

In a sense, yes.
B have implicit reference to Function.prototype, Function.prototype
have implicit reference to Object.prototype.

But there is no explicit reference to the "parent" constructor.
So B.parentConstructor is: function Object(){}.
Nonsense.

At the moment i don't see where to use parentConstructor. And what is
advantage of this? Maybe more readeable code? I don't thing so.

Think again.
Sorry if my post gone to off topic.

Your posting was not off-topic, but it was obviously not very good either.
Please make it better next time.


PointedEars
 
T

Thomas 'PointedEars' Lahn

-TNO- said:
[full-quote]

Apologies for bad formatting.

I don't see an apology for pointless full-quoting here ;-)

If you think that your article is hardly readable (which is not far from the
truth in this case), you should re-post it in what you think is a more
proper fashion, and then remove the bad one. News servers will not notice,
because Google Groups does not send Control messages (unfortunately), but at
least the group's archive would be improved.


HTH

PointedEars
 
A

abozhilov

If you would have read more carefully, you would have noticed that the
future reserved word is spelled `extends' (like in Java, from which it is
most certainly taken).

Oh my god... My eyes mislead that.. Sorry.
No.  Learn to distinguish between property, execution context and scope..  An
object does not have (a) scope (chain); that is only associated with an
execution context.  

Yes, here you are right. My terminology is wrong at the moment. This
will be change.
But there is no explicit reference to the "parent" constructor.

What are you mean about "parent"? And what is explicit reference to
"parent". In:

A

B -> inherit from A

C -> inherit from B

Who is explicit parent of C? Maybe B?
And what is advantage of this technique, when you have explicit
reference to "parent"?
Nonsense.

Allright. Who is the parent constructor of B in that case? Please
explain.
Your posting was not off-topic, but it was obviously not very good either..
Please make it better next time.

I will be try id.
Thanks for response.
 
T

Thomas 'PointedEars' Lahn

abozhilov said:
What are you mean about "parent"? And what is explicit reference to
"parent".

.... constructor: In class-based inheritance, this would be constructor of
the parent/super class; in emulated class-based inheritance in a
prototype-based language, this is the constructor that provides the
prototype object from which the prototype object of the instance about to be
constructed inherits through the prototype chain.
In:

A

B -> inherit from A

You mean: B.prototype inherits from A.prototype (while disregarding, for
brevity, that these are merely object references).
C -> inherit from B

You mean: C.prototype inherits from B.prototype.
Who is explicit parent of C? Maybe B?

Yes. But I was not talking about an "explicit parent", but
about an "explicit reference to the 'parent' constructor".
And what is advantage of this technique, when you have explicit
reference to "parent"?

Told you. In addition, what should go without saying is that the explicit
reference avoids the implicit reference; that is a Good Thing because then
the prototype object from which the prototype of the constructed instance
inherits does not need to provide a `constructor' property. Or, in other
words, referencing the "parent" constructor is independent of the value of
a property with that name then. This is important for true emulation
because class-based inheritance implies specialization by overwriting
inherited methods which often includes calling the overwritten method before
(to perform tasks both classes have in common).
Allright. Who is the parent constructor of B in that case? Please
explain.

The object referred to by `A'.


PointedEars
 
O

optimistx

abozhilov said:
moment i don't see where to use parentConstructor. And what is
advantage of this? Maybe more readeable code? I don't thing so.

Exactly, you proved the point! The point of showing
that example was to show how confusing wrestling one has to do when
using classical inheritance in javascript.

I would like to play with javascript like a child: move / copy / delete /
replace short pieces of data (incl functions) in the 'slots' of objects:

obj = {key1: value1, key2: value2, ... }

When moving/copying/deleting/replacing any slot can be done
any time and functions can receive anything to process why should one
use complicated and confusing pyramides of inheritance
chains?
 
O

optimistx

-TNO- said:

Without getting into anything specific at this point, I found the
following to be an interesting take on prototypes vs classes:
http://www.helsinki.fi/~jppesone/papers/kandi.html

Yes, interesting questions. And in philosophy it is more
fascinating to find the good questions oneself than read
somebody else's answers to questions, which one has
not been aware of.

Once upon a time there were holy big computers, who
were used by priests, and the results of the work were
given to dumb users.

When computers have become commonplace, the priests
have to admit that the users are kings and queens, and
they have the money to pay the priests.

When programming has become the work of the masses,
some of the priests start thinking, that that they are
actually no priests with deep and profound and difficult-to-learn
knowledge of of Software and Hardware. They start
feeling that making programs should be intuitive, easy and
natural process for anyone, even for an old dumb user.

The tools (languages, developement environments)
for making programs should be designed for human beings
in an intuitive and natural way. Is javascript such now?

I think it might be, a subset of it, but I am not sure yet.

The developement of programming:

http://www.infiltec.com/j-h-wrld.htm
 
D

Dmitry A. Soshnikov

function extend(B, A) {

Intermediate = function (){};
Intermediate.prototype = A.prototype;
B.prototype = new Intermediate();
B.prototype.constructor = B;
B.parentConstructor = A;

}

... classical inheritance?

It's actually and only Ñonsequence of a habit to alternative
realizations of OOP-paradigm - why this simple and useful pattern for
*sheaf of prototypes* is called "classcal inheritance"?

ECMAScript is totally and through penetrated by inheritance. The
simple example:

alert(1..toString());

shows the delegation based inheritance and object-oriented ideology of
ECMAScript and which reads like:

1. from primitive value created wrapped object new Number(1);
2. and then called *inherited* method .toString() of that wrapped
object.
2.1 Why inherited? 'cause dynamic mutable objects (which are in
ECMAScript) can have own characteristics (properties and methods) and
wrapped object doesn't have own method .toSting() in this case =>
hence, it *inherits* it (by delegating) from object on which points
(if nothing has been changed) Number.prototype.

So that simple pattern for *sheaf of prototypes* is just useful
"syntactic sugar" and is - native sheaf of prototype chains.

Why it could be called as "classical inheritance"? Only 'cause of
thinking in alternative ideology where inheritance chain should be
*strong and unchangeable* (alternatively to prototype based (PB)
paradigm where delegation chain could be regroup and reorganized in
any moment ('cause of dynamic), and object can change it's prototype
(chain) at any time; actually, in current ECMA-262-3 it's not possible
to change [[Prototype]] after object is created, but, as you know,
some realizations of standard give such ability - for
example: .__proto__; and in next version of standard will
Object.getPrototypeOf(0) which fits ECMAScript to common theory of PB-
paradigm).

Also, why "classical inheritance"? - 'cause of creating own properties
in child-constructors (if, e.g. constructor A creates own property
"this.a", then using pattern showed above and calling
B.parentConstructor.apply(this, arguments) will create own property
for objects created by child-constructor B, which in theory of PB-
paradigm is not required (maybe objects from B don't need to have own
"this.a" property)). In static class based (CB) paradigm properties of
all parent classes in chain *always copy* to child classes (and all
objects, created from such child-class will have *all* parent-
properties, even if it not needed them). So, the main lacks is the
inheritance is deeper, the memory usage is more.

And, btw, not all class based paradigms are totally different from
prototype based. When speaking about difference pair "prototype vs.
class" is not so essential ('cause there're dynamic class based
languages, such as e.g. Python or Ruby where we can see same
principles as in prototype based paradigm). So, the main difference is
"class + static vs. prototype + dynamic".

Example on Python (try to find totally difference from ECMAScript):

<pre><code>

// Python

class A(object):

def __init__(self, a):
self.a = a

def square(self):
return self.a * self.a

a = A(10) // instance
print(a.a) // 10

A.b = 20 // create new property of the class ("prototype")
print(a.b) // 20 - getting it by "delegation" from "a" object

a.b = 30 // create same but own property "b"
print(a.b) // 30

del a.b // delete it
print(a.b) // 20 - again by "delegation" from class ("prototype")

// same as in PB-paradigm, it's possible
// to change class ("prototype") dynamically

class B(object): // "empty" class B
pass

b = B() // instance of B

// like a __proto__ in ES
b.__class__ = A //change class dynamically to A

b.a = 10 // creating new property
print(b.square()) // 100 - and have method of class A

// we can delete explicit references to classes
// as we can delete references (explicit and implicit)
// to constructors and constructor-objects themself
// in ECMASCript
del A
del B

// and object will still have link
// to class ("prototype") object
// by its ("implicit") link such as [[Prototype]] in ES
print(b.square()) // 100

</code></pre>

So, there's no big difference if we're looking from some point of view
(dynamic class-based paradigm, where *class - is also just syntactic
sugar*). But using mentioned above pattern for *sheaf of prototypes*
and saying that it's imitation static CP-paradigm - is wrong, it's not
an imitation, it's just one of *native* ways for *sheaf of
prototypes*.

/ds
 
O

optimistx

-TNO- said:
Why would you ever want to copy and paste identical
code definitions
over and over for multiple objects? Verbose code does not
automatically mean readable code. ....

I don't think you properly understand what a constructor does.

You might be right, therefore I insist on asking simple
down-to-the-earth examples (about abstraction!?).

With copy and paste I mean programmatic copying (e.g. augmenting
objects), not copying program code 'by hand' in the IDE. Sharing
common code in prototypes is understandable and ok, no
problem with that.

If there is a node object with n properties and we need
a more advanced specialnode object with all the properties of
a node plus some more, then in javascript the specialnode can be
created in the constructor by augmenting the node with those new
properties?

When using the created node or specialnode in the program code
like

function useit(anynode){
if (typeof anynode.x ) anynode.x();
}

Polymorfism? How would it work? An example?
 
O

optimistx

optimistx said:
When using the created node or specialnode in the program code
like

function useit(anynode){
if (typeof anynode.x ) anynode.x();
}

Polymorfism? How would it work? An example?

Sorry, I sent that too early: Replace the above with:

Then we use the created node or specialnode in the program code
like

function useit(anynode){
if (typeof anynode.x !== 'undefined') anynode.x();
}

Polymorfism? How would it work? An example?
 
O

optimistx

John G Harris said:
Look no further than the javascript DOM 1 spec if you want a realistic
example :
<http://www.w3.org/TR/REC-DOM-Level-1/>
see the ECMAScript appendix.

There you'll see that HTMLElement objects have all the methods and data
properties of Element objects, which in turn have all the methods and
data properties of Node objects.
....
Yes, that is a good list of information, to be used as a cheatsheet every
day!
"
Object Element
Element has the all the properties and methods of Node as well as the
properties and methods defined below.
The Element object has the following properties:
..."
But but... I do not see why and how I would need some complicated and
mysterious tricks with nodes and elements, wrestle with who would call what
and when and
pray that things turn out to work as I have imagined...

Element has all the properties of Node. So what? If I have a function

function useit(something){
if (typeof something.method1 !== 'undefined') something.method1();
} else {// ? }

and there something can be Node or Element or anything. One has
to check things there anyway (or has one?).

When we construct a Node or Element, we construct it, no complicated
inheritance
studies are needed, finding ancestors, cousins, grandmothers and phoning
them to ask permissions to tolk with their children or friends.( ok, a bit
exaggeration,
to create some artistic impression...).
 
O

optimistx

Dmitry A. Soshnikov wrote:
....
ECMAScript is totally and through penetrated by inheritance. The
simple example:

alert(1..toString());

shows the delegation based inheritance and object-oriented ideology of
ECMAScript and which reads like:

1. from primitive value created wrapped object new Number(1);
2. and then called *inherited* method .toString() of that wrapped
object.
2.1 Why inherited? 'cause dynamic mutable objects (which are in
ECMAScript) can have own characteristics (properties and methods) and
wrapped object doesn't have own method .toSting() in this case =>
hence, it *inherits* it (by delegating) from object on which points
(if nothing has been changed) Number.prototype.


Your insteresting comment inspired to study a little more these typing
matters,
and I made a little newbie script about duck typing

http://www.24.fi/optimistx/clj/ducktype.htm

Duck typing gives polymorfism without inheritance(?), according to wikipedia

wikipedia about duck typing

The above alert(1..toString) remains mysterious for me in spite
your explanations. Two dots! Never see earlier, and that seems to 'work'.
 
T

-TNO-

If there is a node object with n properties and we need
a more advanced specialnode object with all the properties of
a node plus some more, then in javascript the specialnode can be
created in the constructor by augmenting the node with those new
properties?

Is this what you mean?
---------------------------------------------
function Node(foo, bar, baz){
this.foo = foo;
this.bar = bar;
this.baz = baz
}
Node.prototype = {
foo : null,
bar : null,
baz : null,
toString = function(){
//...
}
}

function SpecialNode(a, b, c){
this.a = a;
this.b = b;
this.c = c;
}
SpecialNode.prototype = new Node
("defaultVal","defaultVal","defaultVal")
SpecialNode.prototype.myMethod = function(){
//....
}
SpecialNode.prototype.toString(){
//overwrite the inherited toString
}

var myNode = new SpecialNode(1, 2, 3)

---------------------------------------------
 
T

Thomas 'PointedEars' Lahn

-TNO- said:
Is this what you mean?
---------------------------------------------
function Node(foo, bar, baz){
this.foo = foo;
this.bar = bar;
this.baz = baz
}

This could overwrite the existing Node object as provided e.g. by the Gecko DOM.
Node.prototype = {
foo : null,
bar : null,
baz : null,
toString = function(){
//...
}
}

This could overwrite/shadow the `prototype' property of the existing Node
object.
function SpecialNode(a, b, c){
this.a = a;
this.b = b;
this.c = c;
}
SpecialNode.prototype = new Node
("defaultVal","defaultVal","defaultVal")

That is _not_ the proper way to set up prototypal inheritance. All your
SpecialNode instances would inherit from a single Node instance rather than
from the prototype of Node. We've been over this.
SpecialNode.prototype.toString(){
//overwrite the inherited toString
}

That's junk. If it works at all, its working is implementation-dependent.
var myNode = new SpecialNode(1, 2, 3)

You should end all simple statements with a semicolon.


PointedEars
 
T

-TNO-

This could overwrite the existing Node object as provided e.g. by the Gecko DOM.


This could overwrite/shadow the `prototype' property of the existing Node
object.

That was posted as a generic example, not as some instance of
production code. "function Foo(){...}" would have been a more
appropriate name.
That is _not_ the proper way to set up prototypal inheritance.  All your
SpecialNode instances would inherit from a single Node instance rather than
from the prototype of Node.  We've been over this.

I posted this code as part of the question to the OP, to clarify what
he had in mind. I was "leading the witness" so to speak.
That's junk.  If it works at all, its working is implementation-dependent.

see above.
You should end all simple statements with a semicolon.

The keyword being "should", not "must".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top