Inheritance woes

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

    #1

    Inheritance woes

    This is rediculous. It is said when you override a method in a derived
    class that's implemented in the base class, you "override the base
    class methods" implementation, correct? but in my test,
    base.SomeMethod () still prints out it's *own* implimentation - that's
    tottally different from the deriveds overrided method. I don't get it.
    Really, What's the difference betwen this.SomeMethod () and
    base.SomeMethod ()? more precisely, is *this* and *base* two different
    things, meaning they both reside at a different memory address and each
    have their *own* seperate members, again meaning; different address
    space? To me it looks like a derived class has two seperate members for
    each inherited member in the basde class, one in the derived class
    which can be accessed with *this* and the other completely unrelated
    member, which can be accessed with *base*. I hope someone understands
    my frustration and helps me untangle this confusion.

    Thanks to all who reply.

  • Kevin Spencer

    #2
    Re: Inheritance woes

    "this" is the current implementation (in your case, the derived class).
    "base" is the base class. The difference is that when you call
    base.SomeMethod () you're calling the base class's implementation of the
    method, rather than the override.

    When you inherit a class, you inherit all of it. Overriding a method doesn't
    overWRITE the method. It's still there. And believe it or not, there are
    plenty of cases in which you will *need* it to be there. However, be aware
    that only the derived class instance itself will be able to call the Base
    class method. It still exposes only one (the overridden) implementation.

    --
    HTH,

    Kevin Spencer
    Microsoft MVP
    ..Net Developer
    Who is Mighty Abbott?
    A twin turret scalawag.

    "relient" <xllx.relient.x llx@gmail.com> wrote in message
    news:1137796697 .622397.86320@g 14g2000cwa.goog legroups.com...[color=blue]
    > This is rediculous. It is said when you override a method in a derived
    > class that's implemented in the base class, you "override the base
    > class methods" implementation, correct? but in my test,
    > base.SomeMethod () still prints out it's *own* implimentation - that's
    > tottally different from the deriveds overrided method. I don't get it.
    > Really, What's the difference betwen this.SomeMethod () and
    > base.SomeMethod ()? more precisely, is *this* and *base* two different
    > things, meaning they both reside at a different memory address and each
    > have their *own* seperate members, again meaning; different address
    > space? To me it looks like a derived class has two seperate members for
    > each inherited member in the basde class, one in the derived class
    > which can be accessed with *this* and the other completely unrelated
    > member, which can be accessed with *base*. I hope someone understands
    > my frustration and helps me untangle this confusion.
    >
    > Thanks to all who reply.
    >[/color]


    Comment

    • C.C. \(aka Me\)

      #3
      Re: Inheritance woes

      One way to look at it is that when you override a method you are actually
      "adding" to the code that "can" be executed by that method.

      Here is an example (kind of lame one and may not even even compile) that may
      help you see why it is usefull.

      class FourSidedBox
      {
      public int width;
      public int height;

      public void Draw()
      {
      DrawRectangle(w idth,height);
      }
      }

      class Square: FourSidedBox
      {
      public override void Draw()
      {
      width = 10;
      height = 10;
      base.Draw();
      }
      }

      class Rectangle: FourSidedBox
      {
      public override void Draw()
      {
      width = 20;
      height = 10;
      base.Draw();
      }
      }

      Both of the derived classes (Square and Rectangle) both "add" new
      functionallity to the Draw() method - they set different width and height
      values. They then call the base.Draw() method to actually perform the
      original code as well.

      This also helps you reuse the code in the original Draw() method so you do
      not have to include it in every derived class.

      Lastly.. what if you wanted to change from DrawRectangle() to
      DrawFilledRecta ngle().. You would only have to change it in one place!

      Hope this helps shed some light on how and why it works the way it does..

      And as Martha says... "It's a good thing..."

      "Kevin Spencer" <kevin@DIESPAMM ERSDIEtakempis. com> wrote in message
      news:u8FHiThHGH A.2212@TK2MSFTN GP15.phx.gbl...[color=blue]
      > "this" is the current implementation (in your case, the derived class).
      > "base" is the base class. The difference is that when you call
      > base.SomeMethod () you're calling the base class's implementation of the
      > method, rather than the override.
      >
      > When you inherit a class, you inherit all of it. Overriding a method
      > doesn't overWRITE the method. It's still there. And believe it or not,
      > there are plenty of cases in which you will *need* it to be there.
      > However, be aware that only the derived class instance itself will be able
      > to call the Base class method. It still exposes only one (the overridden)
      > implementation.
      >
      > --
      > HTH,
      >
      > Kevin Spencer
      > Microsoft MVP
      > .Net Developer
      > Who is Mighty Abbott?
      > A twin turret scalawag.
      >
      > "relient" <xllx.relient.x llx@gmail.com> wrote in message
      > news:1137796697 .622397.86320@g 14g2000cwa.goog legroups.com...[color=green]
      >> This is rediculous. It is said when you override a method in a derived
      >> class that's implemented in the base class, you "override the base
      >> class methods" implementation, correct? but in my test,
      >> base.SomeMethod () still prints out it's *own* implimentation - that's
      >> tottally different from the deriveds overrided method. I don't get it.
      >> Really, What's the difference betwen this.SomeMethod () and
      >> base.SomeMethod ()? more precisely, is *this* and *base* two different
      >> things, meaning they both reside at a different memory address and each
      >> have their *own* seperate members, again meaning; different address
      >> space? To me it looks like a derived class has two seperate members for
      >> each inherited member in the basde class, one in the derived class
      >> which can be accessed with *this* and the other completely unrelated
      >> member, which can be accessed with *base*. I hope someone understands
      >> my frustration and helps me untangle this confusion.
      >>
      >> Thanks to all who reply.
      >>[/color]
      >
      >[/color]


      Comment

      • Bruce Wood

        #4
        Re: Inheritance woes

        The first thing you have to distinguish is the difference between
        instance data and code. You get a new copy of instance data every time
        you construct a new instance of your class (via new), but there is only
        one copy of a class's code, which resides in a different place from the
        instance data. So, a running program will have many instances of the
        data members (aka state aka fields) associated with a class stored on
        the heap, but only one, unchanging copy of the code. I know that seems
        irrelevant to your question, but bear with me.

        "this" and "base" can be used to refer to two different things:
        instance data (i.e. fields), and code (e.g. properties, methods). What
        goes on under the covers is different in the two cases.

        Take a look at this example:

        public class A
        {
        protected int _aField;
        }

        public class B : A
        {
        private int _bField;
        }

        The one you didn't ask about was data. Remember that when you
        instantiate a new instance of a derived class (B), the object created
        on the heap will have _two_ fields in it: _aField and _bField. When you
        say "this._bFie ld" in the code, you're referring to the field declared
        in class B ("this"). When you say "this._aFie ld" (or "base._aFie ld")
        then you're referring to the field declared in class A, the base class
        ("base"). Since the fields have different names, you can use "this" or
        "base" to refer to _aField and both will work, because the base class's
        protected and public fields "show through" as though they were declared
        in the derived class.

        Conceptually, using the "base." prefix with data fields just means that
        you're restricting the fields you want to work with (the names that
        follow "base.") to those declared in the base class or below.

        Code works a little differently. Remember that there is only one copy
        of code, regardless of how many objects you instantiate. Expand the
        example above to include a method:

        public class A
        {
        protected int _aField;

        public virtual void AMethod() { }

        public virtual void AMethod2() { }
        }

        public class B : A
        {
        private int _bField;

        public override void AMethod() { }
        }

        Now, there is separate _code_ for each of these classes. There is
        compiled code for class A, containing a method called AMethod(). There
        is also separate compiled code for class B, also containing a method
        called AMethod(). Whether these two compiled classes exist in the same
        assembly or different assemblies, the important point is that there two
        separate compiled bits of code, one for each class.

        The compiled code for class B refers to class A, though, because class
        B knows it's derived from class A, and may need to execute code from
        there from time to time.

        Within class B, the derived class, whenever you say "this." followed by
        a reference to some code, you may be referencing a method in class B
        (if there's one by that name defined there), or you may be referencing
        something defined in class A (if there's something in class A by that
        name and it hasn't been overridden in the derived class, B). So, in the
        example above, if you say "this.AMethod() " then you're talking about
        B's AMethod, because it defines something by that name. If you say
        "this.AMethod2( )" then you're talking about A's AMethod2, because the
        derived class, B, doesn't define anything called AMethod2, so the
        compiler goes up the class hierarchy looking to resolve the name. In
        effect, "this." could result in a call to code in the compiled class B
        _or_ the compiled class A, depending upon how the compiler resolves the
        name.

        So, finally, what's "base" all about? "base" tells the compiler that
        you want to _ignore_ what's defined in the derived class (B) and _only_
        look up the class hierarchy. So, if you say "base.AMeth od", then the
        search to resolve the name starts in class A (the base class of B).

        The language has to provide this feature: what if you want to override
        AMethod in class B, but you want to do a little bit of work _in
        addition to_ what class A's AMethod does? The only way to do this is to
        say:

        public class B : A
        {
        public override void AMethod()
        {
        ... do some stuff ...
        base.AMethod(); // Call my base class's (A's) "AMethod"
        ... do some other stuff ...
        }
        }

        The important point is that this works _only_ from _within_ a class's
        code. Classes outside B can't do this:

        B b = new B();
        b.base.AMethod( );

        or anything like that. From _outside_ the class B, the only method
        called AMethod that the "public" can see is the one defined in B. B,
        however, has access to its parent class's AMethod(), in order to do
        what you saw up above.

        And no, the capability doesn't extend up the hierarchy. There's no such
        thing as "base.base" . So, a class C that looked like this:

        public class C : B
        {
        public override void AMethod()
        { }
        }

        could not call A's AMethod directly, only B's (by saying
        base.AMethod()) .

        Comment

        • relient

          #5
          Re: Inheritance woes

          Bruce Wood wrote:
          <quote>helpfu l stuff</quote>

          OK, first let me say "Thanks a lot" to, Bruce Wood. Impressive,
          detailed - precisely what I needed to know.

          Let me just do an overview of this to brush off any misconceptions and
          or misunderstandin gs I, may still have:

          An overview:
          I know that when you invoke SomeMethod from an instantiated object, the
          compiler secretly passes the object invoking the method as the last
          argument besides the ones already defined (if any), and, this object is
          referenced in the method via the "this" keyword. I also know that When
          you create many instances of an object, you create seperate data
          (related only to it's instantiated object), and not the many others
          created. But, "code", which is methods, properties, indexers etc.. are
          only created once (perhaps during the instantiation of the first
          object?). But the trick to use different data on the same "code" (which
          gives the impression that *n* methods are created for every *n* objects
          you create/instantiate) is by passing the object which is invoking the
          "code" and that's how all instances work and relate to the same piece
          of "code" - I like that.

          Now that, that was addressed, please let me know if I got any of it
          wrong.
          Now to the heart of the question which is in your second example:

          /* But before I begin: just to be on the safe understanding side of
          things; when you say *separate compiled bits of code*, I interperate
          that as *different memory(s) location* - I come from a long C
          background and, distinguishing code, data etc,. as "seperate memory" in
          programming, I have found, helps me a lot in understanding things a
          whole lot better :) */


          public class A
          {
          protected int _aField;


          public virtual void AMethod() { }


          public virtual void AMethod2() { }


          }


          public class B : A
          {
          private int _bField;


          public override void AMethod() { }


          }

          The "Code":
          In the current state of the above two classes, I'm only going to refer
          to the "code" (methods etc,.. not data; fields) for the moment. There
          is three "seperate compiled bits code": There's two that are: AMethod()
          and AMethod2(), which reside in the base class, and then there's the
          overrided AMethod() which resides in the derived classs. These three
          sit on seperate memory, so, base.AMethod() refers to the method defined
          in the base class and this.AMethod() refers to the method defined in
          the derived class (both sit on seperate memory but belong to the same
          object), correct? *But*, if you change the current state of class B,
          the derived class, by removing AMethod(), then there is *only* two
          seperate compiled bits of code, and base.Method() and this.Method()
          refer to, and only, the base Method() - both are the same piece of
          "code" which sit on the same memory. Right?

          The "Data":
          The fields, _aField and _bField, are data. Since data, unlike code, is
          created seperate for each object created, doing this._aField and
          base._aField, refer to *the same memory*. Am I right, again? :D

          Finally, one last question; quite different but still pertaining to the
          topic. override vs new. Is the difference between the two really just
          to serve as "self code documentation" (which gives other potential
          programmers reading your code your true intention)?

          That is all and I'd like to see a response from, Bruce if he gets the
          chance to read my thread again, or anyone. And thanks again, Bruce, I
          think you did a fantastic job in helping me understand how inheritance
          really works.

          Comment

          • Jon Skeet [C# MVP]

            #6
            Re: Inheritance woes

            relient <xllx.relient.x llx@gmail.com> wrote:

            <snip>
            [color=blue]
            > Finally, one last question; quite different but still pertaining to the
            > topic. override vs new. Is the difference between the two really just
            > to serve as "self code documentation" (which gives other potential
            > programmers reading your code your true intention)?[/color]

            No - there's a big, big difference between override and new. See
            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

            for a brief description and example. Let me know if that isn't enough.

            --
            Jon Skeet - <skeet@pobox.co m>
            http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
            If replying to the group, please do not mail me too

            Comment

            Working...