// Static versus dynamic dispatch in C# using System; // base (super) class class AA { public int x = 1; public void f() { Console.WriteLine("calling AA.f, x is "+x); } public virtual void g() // note "virtual" - what does this mean? { Console.WriteLine("calling AA.g, x is "+x); } } // subclass class BB : AA { public new int x = 2; // note "new" public new void f() // note "new" { Console.WriteLine("calling BB.f, x is "+x); } public override void g() // note "override" { Console.WriteLine("calling BB.g, x is "+x); } } public class inheritoptions { public static void Main(string[] args) { AA a = new AA(); BB b = new BB(); ////////// so far, not much is interesting: a.f(); a.g(); b.f(); b.g(); Console.WriteLine("now things get interesting ..."); AA c = new BB(); // c has DIFFERNT static and DYNAMIC types! c.f(); // calls superclass f, x is AA.x c.g(); // calls subclass g, X is BB.x AA d; char x = (char) Console.Read(); // reads a char from stdin if (x=='a') d = new AA(); else d = new BB(); // what is the REAL TYPE OF d????? // it has static type AA, but the runtime type can be AA or BB! d.f(); // no ambiguity here. why? d.g(); // what will this do? It depends on the value of x, // which is obviously only known at runtime. That's why // "virtual"+"override" implement DYNAMIC DISPATCH. ////// see anothertest class below: anothertest at = new anothertest(); object s = "abc"; at.f(s); // ??? at.g("abcd"); } // Main } // In Java, dynamic dispatch is the default - the other option doesn't exist, // so the keywords "virtual" and "override" are not used in Java. They're // there implicitly. // Note also that variables such as "x" are always statically bound. // It's not possible to use "override" on a variable. Thus sometimes // you see code that looks like // int x() { return 3; } // and you might wonder why not just say " int x = 3". The reason is // you can override the method x() in a subclass, but not a variable ///////////////// Overloading != Dynamic Dispatch /////////////////// class anothertest { public void f(string x) { Console.WriteLine("String version of f called"); } public void f(object x) { Console.WriteLine("Object version of f called"); } public void g(object x) { Console.WriteLine("g called on object "+x); } }