New vs Override

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • methodios

    #1

    New vs Override

    Hi
    Can someone help me straighten out my train of thought... I want to
    know what actually goes on behind the scene..step by step.

    Here is the code:

    -----------------
    using System;

    namespace Test
    {
    public class MyBase
    {
    public virtual string Meth1()
    {
    return "MyBase-Meth1";
    }
    public virtual string Meth2()
    {
    return "MyBase-Meth2";
    }
    }


    class MyDerived : MyBase
    {
    public override string Meth1()
    {
    return "MyDerived-Meth1";
    }
    public new string Meth2()
    {
    return "MyDerived-Meth2";
    }


    public static void Main()
    {
    MyDerived mD = new MyDerived();
    MyBase mB = (MyBase) mD;



    System.Console. WriteLine(mD.Me th1()); // Displays: MyDerived-Meth1
    System.Console. WriteLine(mB.Me th1()); // Displays: MyDerived-Meth1
    System.Console. WriteLine(mB.Me th2()); // Displays: MyBase-Meth2
    System.Console. WriteLine(mD.Me th2()); // Displays: MyDerived-Meth2
    }


    }

    }

    -------
    Here is what I think is currently happening (please correct me if I'm
    wrong).
    Question 1) When mD.Meth1() is called, it checks the memory locaton in
    the heap contained in mD and goes to that location. Now, it finds the
    MyDerived object.

    **HERE IS WHERE MY CONFUSION BEGINS**
    What does it actually do? Does it do the following:
    PATH 1 - Go into MyDerived and realize it's inheriting MyBase. It then
    goes to MyBase and finds Meth1() and notice it to be a virtual
    function. It comes back out of MyBase and goes back to MyDerived and
    notice that the function has been correclty overriden and uses that
    function.

    OR

    PATH 2 - Go into MyDerived and does not even bother going into MyBase.
    It notices that it has that function in it and it's overridding the
    base function and calls it.



    Quesiton 2) When mB.Meth2() is called, since the object really being
    used is still MyDerived, how come MyDerived.Meth2 () isn't called? The
    new function obviously hides it, and the object being worked on is
    MyDervived...no t MyBase.

    Why does it take PATH 1 and go into MyBase and calls that function when
    the function has a keyword NEW which hides it?

    Please help!!!

  • Jesse McGrew

    #2
    Re: New vs Override

    methodios wrote:[color=blue]
    > Here is what I think is currently happening (please correct me if I'm
    > wrong).
    > Question 1) When mD.Meth1() is called, it checks the memory locaton in
    > the heap contained in mD and goes to that location. Now, it finds the
    > MyDerived object.
    >
    > **HERE IS WHERE MY CONFUSION BEGINS**
    > What does it actually do? Does it do the following:
    > PATH 1 - Go into MyDerived and realize it's inheriting MyBase. It then
    > goes to MyBase and finds Meth1() and notice it to be a virtual
    > function. It comes back out of MyBase and goes back to MyDerived and
    > notice that the function has been correclty overriden and uses that
    > function.
    >
    > OR
    >
    > PATH 2 - Go into MyDerived and does not even bother going into MyBase.
    > It notices that it has that function in it and it's overridding the
    > base function and calls it.[/color]

    The latter.

    Every class has a table with slots for each virtual method in the
    class, where each slot points to the implementation of that method.
    When you override a method in a derived class, the new implementation
    simply replaces the old one in the derived class's virtual method
    table. Calling a virtual method means looking up the virtual method
    table, finding the slot corresponding to the method you want, and
    jumping to the address found there. The type of the object doesn't
    really even matter, only the addresses stored in the table.

    We can imagine the table for MyBase looking like this (ignoring the
    virtual methods inherited from System.Object, like ToString):

    "Meth1" -> MyBase.Meth1
    "Meth2" -> MyBase.Meth2

    And for MyDerived:

    "Meth1" -> MyDerived.Meth1
    "Meth2" -> MyBase.Meth2

    Since you used the "new" keyword, the compiler knows that
    MyDerived.Meth2 isn't the same method as MyBase.Meth2, so mD.Meth2()
    results in a call to the new method, not the old one. However, it can
    only use that information when you call through a variable of the
    derived type. When you call through a MyBase variable, the compiler can
    only see the Meth2 defined in MyBase.
    [color=blue]
    > Quesiton 2) When mB.Meth2() is called, since the object really being
    > used is still MyDerived, how come MyDerived.Meth2 () isn't called? The
    > new function obviously hides it, and the object being worked on is
    > MyDervived...no t MyBase.[/color]

    This is precisely the difference between overriding and hiding.
    MyDerived.Meth2 isn't actually related to MyBase.Meth2; they just
    happen to have the same name. At compile time, the method call is bound
    to the derived version, not the base version, because of the type of
    the variable you're using to call the method.

    Jesse

    Comment

    • Michael S

      #3
      Re: New vs Override

      "Jesse McGrew" <jmcgrew@gmail. com> wrote in message
      news:1134638135 .423570.157710@ z14g2000cwz.goo glegroups.com.. .[color=blue]
      > methodios wrote:[color=green]
      >> Here is what I think is currently happening (please correct me if I'm
      >> wrong).
      >> Question 1) When mD.Meth1() is called, it checks the memory locaton in
      >> the heap contained in mD and goes to that location. Now, it finds the
      >> MyDerived object.
      >>
      >> **HERE IS WHERE MY CONFUSION BEGINS**
      >> What does it actually do? Does it do the following:
      >> PATH 1 - Go into MyDerived and realize it's inheriting MyBase. It then
      >> goes to MyBase and finds Meth1() and notice it to be a virtual
      >> function. It comes back out of MyBase and goes back to MyDerived and
      >> notice that the function has been correclty overriden and uses that
      >> function.
      >>
      >> OR
      >>
      >> PATH 2 - Go into MyDerived and does not even bother going into MyBase.
      >> It notices that it has that function in it and it's overridding the
      >> base function and calls it.[/color]
      >
      > The latter.
      >
      > Every class has a table with slots for each virtual method in the
      > class, where each slot points to the implementation of that method.
      > When you override a method in a derived class, the new implementation
      > simply replaces the old one in the derived class's virtual method
      > table. Calling a virtual method means looking up the virtual method
      > table, finding the slot corresponding to the method you want, and
      > jumping to the address found there. The type of the object doesn't
      > really even matter, only the addresses stored in the table.
      >
      > We can imagine the table for MyBase looking like this (ignoring the
      > virtual methods inherited from System.Object, like ToString):
      >
      > "Meth1" -> MyBase.Meth1
      > "Meth2" -> MyBase.Meth2
      >
      > And for MyDerived:
      >
      > "Meth1" -> MyDerived.Meth1
      > "Meth2" -> MyBase.Meth2
      >
      > Since you used the "new" keyword, the compiler knows that
      > MyDerived.Meth2 isn't the same method as MyBase.Meth2, so mD.Meth2()
      > results in a call to the new method, not the old one. However, it can
      > only use that information when you call through a variable of the
      > derived type. When you call through a MyBase variable, the compiler can
      > only see the Meth2 defined in MyBase.
      >[color=green]
      >> Quesiton 2) When mB.Meth2() is called, since the object really being
      >> used is still MyDerived, how come MyDerived.Meth2 () isn't called? The
      >> new function obviously hides it, and the object being worked on is
      >> MyDervived...no t MyBase.[/color]
      >
      > This is precisely the difference between overriding and hiding.
      > MyDerived.Meth2 isn't actually related to MyBase.Meth2; they just
      > happen to have the same name. At compile time, the method call is bound
      > to the derived version, not the base version, because of the type of
      > the variable you're using to call the method.
      >
      > Jesse[/color]

      Well written Jesse.

      Also just to add:

      A reintroduced call is fast as the compiler can go the type od the reference
      and simply call the method.

      A overridden call is slower as the runtime must access your object, access
      its type (VTable) and call the correct method.

      - Michael S

      ps.
      I still think that Delphis keyword 'reintroduce' is better than 'new'


      Comment

      • Brian Gideon

        #4
        Re: New vs Override

        In addition to what others have said notice that you get the same
        behavior without the 'new' modifier. You do get a warning from the
        compiler telling you that a derived class is hiding an inherited
        member. The 'new' modifier is a way to explicitly tell the compiler
        that hiding is indeed what you intended. But, it doesn't actually
        change the execution of code in any way. That's a good thing. Let me
        give you a practical example to show you why.

        Consider the following code.

        // This is provided by the Wizbang Widget Company
        public class Widget
        {
        public virtual void Foo() { }
        public virtual void Bar() { }
        }

        // You decide to extend the Widget class to make it better.
        public class BetterWidget : Widget
        {
        public void Initialize()
        {
        // Code to initialize the class goes.
        }
        }

        Later, the Wizbang Widget Company decides that they need to add a
        mechanism for initializing the Widget so naturally they add an
        Initialize method.

        public class Widget
        {
        public virtual void Foo() { }
        public virtual void Bar() { }
        public void Initialize() { }
        }

        Can you believe that. They added a method to their Widget class with
        the same name as an existing method in your derived class! What are
        the odds of that?!

        In this case all existing BetterWidget references will still use the
        BetterWidget.In itialize implementation and any new uses of the
        Initalize method on a Widget reference will use the Widget.Initiali ze
        method. You will get a compiler warning, but everything works as
        expected without any modifications to the code.

        Can you see why it would have been worse had the C# compiler generated
        an error or changed the way the methods were called?

        Brian

        methodios wrote:[color=blue]
        > Hi
        > Can someone help me straighten out my train of thought... I want to
        > know what actually goes on behind the scene..step by step.
        >
        > Here is the code:
        >
        > -----------------
        > using System;
        >
        > namespace Test
        > {
        > public class MyBase
        > {
        > public virtual string Meth1()
        > {
        > return "MyBase-Meth1";
        > }
        > public virtual string Meth2()
        > {
        > return "MyBase-Meth2";
        > }
        > }
        >
        >
        > class MyDerived : MyBase
        > {
        > public override string Meth1()
        > {
        > return "MyDerived-Meth1";
        > }
        > public new string Meth2()
        > {
        > return "MyDerived-Meth2";
        > }
        >
        >
        > public static void Main()
        > {
        > MyDerived mD = new MyDerived();
        > MyBase mB = (MyBase) mD;
        >
        >
        >
        > System.Console. WriteLine(mD.Me th1()); // Displays: MyDerived-Meth1
        > System.Console. WriteLine(mB.Me th1()); // Displays: MyDerived-Meth1
        > System.Console. WriteLine(mB.Me th2()); // Displays: MyBase-Meth2
        > System.Console. WriteLine(mD.Me th2()); // Displays: MyDerived-Meth2
        > }
        >
        >
        > }
        >
        > }
        >
        > -------
        > Here is what I think is currently happening (please correct me if I'm
        > wrong).
        > Question 1) When mD.Meth1() is called, it checks the memory locaton in
        > the heap contained in mD and goes to that location. Now, it finds the
        > MyDerived object.
        >
        > **HERE IS WHERE MY CONFUSION BEGINS**
        > What does it actually do? Does it do the following:
        > PATH 1 - Go into MyDerived and realize it's inheriting MyBase. It then
        > goes to MyBase and finds Meth1() and notice it to be a virtual
        > function. It comes back out of MyBase and goes back to MyDerived and
        > notice that the function has been correclty overriden and uses that
        > function.
        >
        > OR
        >
        > PATH 2 - Go into MyDerived and does not even bother going into MyBase.
        > It notices that it has that function in it and it's overridding the
        > base function and calls it.
        >
        >
        >
        > Quesiton 2) When mB.Meth2() is called, since the object really being
        > used is still MyDerived, how come MyDerived.Meth2 () isn't called? The
        > new function obviously hides it, and the object being worked on is
        > MyDervived...no t MyBase.
        >
        > Why does it take PATH 1 and go into MyBase and calls that function when
        > the function has a keyword NEW which hides it?
        >
        > Please help!!![/color]

        Comment

        Working...