Solved

Calling a superclass method inside an overrided method

Posted on 1998-11-15
13
369 Views
Last Modified: 2012-06-27
I haven't found the syntax to call a superclass function
from inside an overrided function.  For instance:

function Item(price) {
      this.price = price || null;
      this.writeInfo = Item_writeInfo;
      return this;
}
function Item_writeInfo() {
      write("Price: " + price + "<br>\n");
}

function LibraryItem(price, location) {
      this.location = location;
      this.price = price;
      this.writeInfo = LibraryItem_writeInfo;
      return this;
}
LibraryItem.prototype = new Item();

function LibraryItem_writeInfo() {
      // Now here I'd like to call Item_writeInfo
      // In Java it would be:
      // super.writeInfo();
      write('Location: ' + this.location + "<br>\n");
}

Is there any way to do this elegantly?
0
Comment
Question by:nmoldav
  • 6
  • 3
  • 2
  • +2
13 Comments
 

Author Comment

by:nmoldav
ID: 1274038
Adjusted points to 400
0
 
LVL 4

Expert Comment

by:martinag
ID: 1274039
Does this work?
function LibraryItem_writeInfo() {
  t = Item(price);
  t.writeInfo();
  write('Location: ' + location + "<br>\n");
}

Martin
0
 

Author Comment

by:nmoldav
ID: 1274040
Edited text of question
0
 

Author Comment

by:nmoldav
ID: 1274041
Martin, your code works with some modifications, but
it's not quite elegant because you've to hardcode
the superclass name and create a new object.  I've
already done something similar but I was actually
looking for a simpler solution.  I've tried using
the __proto__ attribute but it didn't work:

function LibraryItem_writeInfo() {
      this.__proto__.writeInfo();
      write('Location: ' + this.location + '<br>\n');
}

Actually, it works here but the function I'm using
doesn't just read attributes but adds new ones
and if I call the 'superclass' function using __proto__
the new attributes don't end up where I want them.

0
 
LVL 2

Expert Comment

by:Quixote
ID: 1274042
I'm kind of puzzled as to what you are trying to do, but I do know that you are using the prototype property incorrectly.  To do something similar to what you are saying (I think), do this:

LibraryItem.prototype.super = new Item();

And now LibraryItem.super.writeInfo is Item_writeInfo(), but LibraryItem.writeInfo is still LibraryItem_writeInfo()

Is that what you mean?


Another problem you may be having is your use of

this.price = price || null;

.which is not supported on all platforms.  You should probably write it as:

this.price = (price) ? price : null;


Hope that helps.


Cheers.
-Quixote
0
 
LVL 10

Expert Comment

by:kollegov
ID: 1274043
<html>
<script>

function Item_writeInfo()
{document.writeln('Price: ' + this.price + '<br>\n');}

function Item(price)
{this.price = price || null;
 return this;
}
Item.prototype.Item_writeInfo = Item_writeInfo;

LibraryItem.prototype=Item.prototype
function LibraryItem(price, location)
{  this.price = price;
   this.location = location;
   return this;
}


function LibraryItem_writeInfo()
{  this.Item_writeInfo();
   document.writeln('Location: ' + this.location + "<br>\n");
}

LibraryItem.prototype.LibraryItem_writeInfo = LibraryItem_writeInfo;


</script>
<body>

<script>

document.writeln('CREATING:  new LibraryItem(50," bookshelf")<br>');
var vvv = new LibraryItem(50," bookshelf");

document.writeln("<h2>vvv.Item_writeInfo():</h2>");
vvv.Item_writeInfo();
document.writeln("<h2> vvv.LibraryItem_writeInfo():</h2>");
vvv.LibraryItem_writeInfo();

</script>

</body>
</html>

Isn't it what you was asking for?
Sorry I changed write to document.writeln
just for easy testing :)
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:nmoldav
ID: 1274044
Kollegov,
that's not exactly was I was looking for.  In fact, I had
done something similar and then I posted the question to
see if there was a more elegant way around.  I don't like
this approach because inside LibraryItem_writeInfo()
you call this.Item_writeInfo.  The fact I don't like is that
you've already defined that LibraryItem inherits from Item
so there should be a way of calling its superclass method without
having to write the complete name.  

In other words, I was looking for something along the lines of:
super() or this.super() or this.super.writeInfo()
instead of this.Item_writeInfo()

After posting the question I tried this.__proto__.writeInfo()
but I had a few problems.

0
 
LVL 10

Accepted Solution

by:
kollegov earned 400 total points
ID: 1274045
Hmmm.....
Looks like you missunderstanding 'prototype' property

"A value from which instances of a particular class are created. Every object that can be created by calling
a constructor function has an associated prototype property...
.......................
You can add new properties or methods to an existing class by adding them to the prototype associated
with the constructor function for that class. The syntax for adding a new property or method is:
"

What does this mean? This mean that you have no mechanism
for subclassing, you are changing existing class.
As well as you have no way for subclassing.

So you can only overwrite (not overread) methods in
Item class, so the original method will be lost forever.

Well, well, well
You sure can inherit manually like i do in this example
below:

<html>
<script>

function Item_writeInfo()
 {document.writeln('Price: ' + this.price + '<br>\n');}

function Item(price)
 {this.price = price || null;
  this.writeInfo = Item_writeInfo
  return this;
 }

LibraryItem.prototype = Item.prototype
function LibraryItem(price, location)
    {  //inherit manually what you need to inherit
       this.mysuper = new Item(price)
       this.price   = this.mysuper.price;
       // in the same way you can inherit methods
       
       this.location=location
       this.writeInfo = LibraryItem_writeInfo
       return this;
    }


function LibraryItem_writeInfo()
  {  this.mysuper.writeInfo();
     document.writeln(this.price+' Location: ' + this.location + "<br>\n");
  }



     </script>
     <body>

     <script>

     document.writeln('CREATING:  new LibraryItem(50," bookshelf")<br>');
     var libitem = new LibraryItem(50," bookshelf");

     document.writeln('CREATING:  new Item(55)<br>');
     var item = new Item(55);

     document.writeln("<h2>libitem.writeInfo():</h2>");
     libitem.writeInfo();

     document.writeln("<h2>item.writeInfo():</h2>");
     item.writeInfo();
     

     </script>

     </body>
     </html>





0
 

Author Comment

by:nmoldav
ID: 1274046
I've reread your comment and the document on Object Hierarchy
and Inheritance in JavaScript and it seems I was taking a
different approach.  I understand now why you can't override
methods without loosing the original ones.  However, the way
I was creating the objects it is possible to do so.  Please
take a look at the following code.  Perhaps you might argue
it's not real inheritance.  

<html>
<script Language="JavaScript1.2">
function Item(price) {
        this.price = price || 0;
        this.writeInfo = Item_writeInfo;
}
function Item_writeInfo() {
        alert("My price is " + this.price);
}

function LibraryItem(price, location) {
        this.__proto__.price = price;
        this.location = location;
        this.writeInfo = LibraryItem_writeInfo;
}
LibraryItem.prototype = new Item;
function LibraryItem_writeInfo() {
      // Call the 'superclass' overrided method
        this.__proto__.writeInfo();
        alert("My location is " + this.location);
}
</script>
<body>
<form>
Price: <input type=text name=price><br>
Location: <input type=text name=location><br>
<input type=button value="run" onClick="JavaScript: var a = new LibraryItem(this.form.price.value, this.form.location.value); a.writeInfo();">
</form>
</body>
</html>

0
 
LVL 10

Expert Comment

by:kollegov
ID: 1274047
Actually what do this line :?)
LibraryItem.prototype = new Item;

If you read definitions of prototype property and think about it
you will find that it's equivalent to:

function LibraryItem(price, location)
{  //inherit manually what you need to inherit
   this.mysuper = new Item(price)
   //... so on...
}

The difference is that in my case I create 'mysuper' property.
and in first way this property is predefined '__proto__'
Hmmmm....

BTW I was very surprized, the "Object Hierarchy and Inheritance in JavaScript" document is only place where __proto__ mentioned.
When I greped through the JavaScript references I didn't find it
documented :)  Should be I guess :)

As I never read this article before I just invented equivalent
for this undocumented (in references) property.
(Just curious how many times I invented bycicles in my life,
 Each day here, learn something new :)

Thanks, your question was very interesting ...

As for your actual code problems, I think the problem
is in some other minor bug.

0
 

Author Comment

by:nmoldav
ID: 1274048
It's funny.  I had read the Object Hierarchy article
before starting this project but I did not notice that
you were supossed to call the 'superclass constructor'
inside the subclass constructor.  I.e:

function LibraryItem(price, location)
      {  //inherit manually what you need to inherit
         this.mysuper = new Item(price)
         //... so on...
      }

I created several objects without ever calling
this.mysuper = new Item(price), but just using

LibraryItem.prototype = new Item;

There's a difference in these two methods.  The way
I did it, whenever you attempt to read or reference
an attribute, for instance, this.price, JavaScript
will try to find the attribute in the current object (this).
If it doesn't find it, it will look in this.__proto__,
this.__proto__.__proto__ and so on..  This is good.

However, when you try to *set* an attribute it will
set it on this, without checking if it already exists
in this.__proto__.  So, if you have

this.__proto__.price = 1;
alert("this.price = " + this.price); // Will print 1
this.price = 2 // This will set this.price, not
               // change this.__proto__.price
alert("this.price = " + this.price); // Will print 2
alert("this.__proto__.price = " + this.__proto__.price);
      // will print 1

So there are two price attributes.  This is bad.  It
should check all the hierarchy to see if an attribute
exists  before creating a new attribute on this.

Why does this matters?  Because if you call a
method on this.__proto__, the method will only be
able to read properties defined on this.__proto__
and won't be able to access the ones defined on this.
That is to say, if inside the LibraryItem constructor
I had set
this.price = price
instead of
this.__proto__.price = price
then this.__proto__.writeInfo() would have always
printed 0, no matter what the this.price attribute's
value was.


So I guess this could be defined as 'read-only
attribute inheritance'. ;-)  

My code didn't work  because I was
setting the attributes on this instead of
on this.__proto__.  I posted the question after
doing some sort of manual inheritance and realizing
it wasn't very elegant.  

Anyway, so much for this.  Thanks for your
help.  

      Nicolas

0
 

Expert Comment

by:Tcchou
ID: 3800161
The following program may be the answer:
(I am working in Win98 with IE 5.5)

<SCRIPT LANGUAGE=javascript>
function Item(price)
{
      this.price = price;
      this.writeInfo = Item_writeInfo;
}

function Item_writeInfo()
{
      document.write("Price: " + this.price + "<br>");
}

function LibraryItem(price, location)
{
      this.location = location;
      LibraryItem.prototype.constructor(price);
      this.writeInfo = LibraryItem_writeInfo;
}
LibraryItem.prototype = new Item();

function LibraryItem_writeInfo()
{
      LibraryItem.prototype.writeInfo();
      document.write('Location: ' + this.location + "<br>");
}

var test=new LibraryItem(20,"Taipei");
test.writeInfo();
</SCRIPT>

The output of this program:
Price: 20
Location: Taipei
0
 

Expert Comment

by:Tcchou
ID: 3823034
I just found a simple way to accomplish:
 
<SCRIPT LANGUAGE=javascript>
function Item(price)
{
      this.price = price;
      this.writeInfo = Item_writeInfo;
}

function Item_writeInfo()
{
      document.write("Price: " + this.price + "<br>");
}

function LibraryItem(price, location)
{
      this.location = location;
      Item.prototype.constructor(price);
      this.writeInfo = LibraryItem_writeInfo;
}

function LibraryItem_writeInfo()
{
      Item.prototype.writeInfo();
      document.write('Location: ' + this.location + "<br>");
}

var test=new LibraryItem(20,"Taipei");
test.writeInfo();
</SCRIPT>
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

I've been trying to accomplish this for a while and it just struck me yesterday how to accomplish this task. I have done searches all over the internet looking for ways to email pages from my applications and finally I have done it!!! Every single s…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now