473,320 Members | 1,940 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

question about calling a method (more fun with polymorphism)

I have a question about how one of these methods is called. The call

theNote.Write();

uses the Write() method in the Document class, and not the Write()
from the Note class. Why is this? theNote is a Note type, isn't it? So
shouldn't it call the method from the derived class? Or does it have
something to do with the fact that the Write() method in Note uses the
new keyword?

Basically, I understand how Read() is overridden, but I don't
understand how the Write() method is being called in this example.

The code:
-----------------

#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion

namespace overridingInterface
{
interface IStorable
{
void Read();
void Write();
}

// Simplify Document to implement only IStorable
public class Document : IStorable
{
// the document constructor
public Document( string s )
{
Console.WriteLine(
"Creating document with: {0}", s );

}

// Make read virtual

public virtual void Read()
{
Console.WriteLine(
"Document Read Method for IStorable" );
}

// NB: Not virtual!
public void Write()
{
Console.WriteLine(
"Document Write Method for IStorable" );
}

}

// Derive from Document
public class Note : Document
{
public Note( string s ):
base(s)
{
Console.WriteLine(
"Creating note with: {0}", s );
}

// override the Read method

public override void Read()
{
Console.WriteLine(
"Overriding the Read method for Note!" );
}

// implement my own Write method
public new void Write()
{
Console.WriteLine(
"Implementing the Write method for Note!" );
}
}
public class Tester
{

static void Main()
{
// create a document object
Document theNote = new Note( "Test Note" );
IStorable isNote = theNote as IStorable;
if ( isNote != null )
{
isNote.Read();
isNote.Write();
}

Console.WriteLine( "\n" );

// direct call to the methods
theNote.Read();
theNote.Write();

Console.WriteLine( "\n" );

// create a note object
Note note2 = new Note( "Second Test" );
IStorable isNote2 = note2 as IStorable;
if ( isNote2 != null )
{
isNote2.Read();
isNote2.Write();
}

Console.WriteLine( "\n" );

// directly call the methods
note2.Read();
note2.Write();
}
}
}
Nov 17 '05 #1
6 1362

"John Salerno" wrote...
I have a question about how one of these
methods is called. The call

theNote.Write();

uses the Write() method in the Document class, and
not the Write() from the Note class. Why is this?
theNote is a Note type, isn't it? So shouldn't it call
the method from the derived class? Or does it have
something to do with the fact that the Write() method
in Note uses the new keyword?


When a method not is constructed with the virtual keyword in the base class,
it simply looks in the "method list" for the declared type of the
*variable*, not the type for the instance.

In the test program:

Document theNote = new Note( "Test Note" );

....which means that non-overridden (non-virtual) methods will use the
implementation of Document, not implementations in the subclass.

Personally, I think it was a mistake from Microsoft's part to limit the
possibilities of polymorphism this way...

// Bjorn A
Nov 17 '05 #2
This may help:

Chapter 8 "Shadow Fields, Override Virtual Methods"

http://www.geocities.com/jeff_louie/OOP/oop8.htm

Regards,
Jeff
Or does it have something to do with the fact that the Write() method

in
Note uses thenew keyword? <

*** Sent via Developersdex http://www.developersdex.com ***
Nov 17 '05 #3
When you declare a method as "virtual", what you're telling the
compiler is that you want to defer until run-time the decision about
which method (from which level in the class hierarchy) should really be
called when you say, for example, "Read()".

If you don't declare a method "virtual" then you are saying that the
compiler should make the final decision about which method should be
called.

Now, here you have to make a careful distinction between compile time
and run time, between what the compiler knows (which is limited), and
what is the reality when the code is running. When you say,

Document theNote = new Note("Test Note");

you are telling the compiler that theNote is a Document. Now, at run
time, the CLR will know that it is really a particular kind of Document
called a Note, but that is only because it has the real, instantiated
Note at its disposal (because it's running the code). The compiler
couldn't figure that out without... well, it just couldn't.

So, the compiler thinks that theNote is a Document. Since Write() isn't
virtual, you've left it up to the compiler to decide which method to
call, so it calls Document.Write().

In the case of Read(), which is virtual, the compiler defers the
decision to the run-time. It says, "Call the Read() method of the type
of the object that theNote points to". At run time, theNote points to a
Note, so the run time decides to call Note.Read(). Again, because you
declared it virtual.

To Bjorn I would add, no, it wasn't a mistake. It was an efficiency
decision. Virtual methods cause increased memory consumption and slower
execution. Not much, but over millions of method calls and millions of
objects, it all adds up. Java's solution was to assume that everything
is virtual unless you specifically state otherwise. The MS team noted
that most programmers don't bother, so they took the opposite tack: you
get virtual methods only when you explicitly state that you want them.
This doesn't "limit polymorphism" in any way. It just means that you
don't get it unless you ask for it.

Nov 17 '05 #4
Jeff Louie wrote:
This may help:

Chapter 8 "Shadow Fields, Override Virtual Methods"

http://www.geocities.com/jeff_louie/OOP/oop8.htm

Regards,
Jeff
Or does it have something to do with the fact that the Write() method


in
Note uses thenew keyword? <

*** Sent via Developersdex http://www.developersdex.com ***


Thanks guys. I think I need to read up a bit more about OOP specifically.
Nov 17 '05 #5
John Salerno <jo******@NOSPAMgmail.com> wrote:
I have a question about how one of these methods is called. The call

theNote.Write();

uses the Write() method in the Document class, and not the Write()
from the Note class. Why is this? theNote is a Note type, isn't it? So
shouldn't it call the method from the derived class? Or does it have
something to do with the fact that the Write() method in Note uses the
new keyword?


Absolutely. You're not overriding Document.Write in Note, you're
creating a new method which also happens to be called Note. That isn't
visible to theNote, as the type of the theNote variable is Document.

See http://www.pobox.com/~skeet/csharp/faq/#override.new

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #6
Jon Skeet [C# MVP] wrote:
John Salerno <jo******@NOSPAMgmail.com> wrote:
I have a question about how one of these methods is called. The call

theNote.Write();

uses the Write() method in the Document class, and not the Write()
from the Note class. Why is this? theNote is a Note type, isn't it? So
shouldn't it call the method from the derived class? Or does it have
something to do with the fact that the Write() method in Note uses the
new keyword?

Absolutely. You're not overriding Document.Write in Note, you're
creating a new method which also happens to be called Note. That isn't
visible to theNote, as the type of the theNote variable is Document.

See http://www.pobox.com/~skeet/csharp/faq/#override.new


Great link. That helped a lot to explain it, and I'm sure the other
questions will be great to read as well.
Nov 17 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

39
by: scooter | last post by:
Given this class heirarchy class Base{}; class A : public Base {}; class B : public Base {};
7
by: DJ.precario | last post by:
In a schematic way, I have a program with a virtual base class (MyClass), and some derived classes (MyClass1, Myclass2...) In main, I want to create a vector of objects of the classes that...
3
by: John Salerno | last post by:
Along with events and delegates, polymorphism has been something I sort of struggle with every now and then. First, let me quote the book I'm reading: "Polymorphism is most useful when you have...
1
by: relient | last post by:
Hi, I just started the chapter on "Inheritance" and I'm a bit confused so I have three questions: first, here's the code: using System; using System.Collections.Generic; using System.Text; ...
9
by: davetelling | last post by:
I am not a programmer, I'm an engineer trying to make an interface to a product I'm designing. I have used C# to make a form that interrogates the unit via the serial port and receives the data. I...
9
by: James Crosswell | last post by:
I'm not sure if I'm going about this the right way - it may be that Generics might be able to help me out here... but here goes: I have three classes as follows class BaseEdit class WidgetEdit:...
7
by: Markus Svilans | last post by:
Hello, My question involves virtual functions and inheritance. Suppose we have a class structure, that consists of "data" classes, and "processor" classes. The data classes are derived from...
122
by: C.L. | last post by:
I was looking for a function or method that would return the index to the first matching element in a list. Coming from a C++ STL background, I thought it might be called "find". My first stop was...
4
by: Jon Skeet [C# MVP] | last post by:
On Aug 11, 5:11 am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com> wrote: Exactly. My favourite example is Thread.Sleep. Suppose this code were valid (its equivalent in Java is, for example): ...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.