-2

We have two classes A and B, B Derives from A, I created of A a = new B(); Why in my code when I call method of B that does not contain A I get error. Does it mean that Type Object Pointer is of type A? and second why When I call SomeMethod it calls method of A not B?

In the heap in this situation when created object instance, type object pointer points to A or B?

class A
{
    public void SomeMethod()
    {
        Console.Write("This is A");
    }
}

class B : A
{
    public void SomeMethod()
    {
        Console.Write("This is B");
    }

    public void OtherMethod()
    {
        Console.Write("This is New method");
    }
}
class Program
{
    static void Main(string[] args)
    {
        A a = new B();

        a.SomeMethod(); // This is A method
        a.OtherMethod(); // I get error here that a does not contain definition for this method

    }
}
Simply Ged
  • 8,250
  • 11
  • 32
  • 40
  • Read @TheGeneral's answer. Basically, when you create `SomeMethod` both in the base-class and in the sub-class, you have a choice. If you want them to be related, create the base-class version as `virtual` and the sub-class version as `override`. If you want to have the sub-class version _replace_ the base class version (when called via a sub-class reference), use the `new` keyword. Consider if you have a base class called `Cowboy` and a method `Draw` (implying drawing a gun). If your sub-class is `CowboyArtist`, and you want the `Draw` method to use a pencil, use `new` – Flydog57 Jan 03 '19 at 23:30
  • Possible duplicate of [Difference between shadowing and overriding in C#?](https://stackoverflow.com/questions/392721/difference-between-shadowing-and-overriding-in-c) – mjwills Jan 03 '19 at 23:39
  • 1
    Your heap question seems a little confused. If you instantiate a variable of type X then the object on the heap is of type X. It really is that simple. _As a side issue - this is also why you should ask only one question per post - https://meta.stackexchange.com/questions/222735/can-i-ask-only-one-question-per-post ._ – mjwills Jan 03 '19 at 23:48
  • Don't think about heaps and pointers. Instead, draw a box 1 inch (or 1 cm) square, label it `A`. Now draw another box 1 inch (/cm) wide, but 2 high. Label it `B` (at the bottom). Inside that box, flush with the top, draw another 1x1 box. Label it `A` as well. Your first box represents an `A` created like this `var a = new A();`. The second box is the result of `var b = new B();`. It contains a full `A`, but is a `B`. If you say `var aInB = (A) b`, now you are referencing that `B` object, but you are only seeing it as an `A` (i.e., the inner box that is an `A`) – Flydog57 Jan 04 '19 at 00:19
  • `It contains a full A` I am not sure I'd use that terminology with a new programmer. A male doesn't **contain** a person. They **are** a person. Using the language of `contains` makes it sound like there is some way to get access to the person within me. There isn't. – mjwills Jan 04 '19 at 00:43
  • Can I say that A a = new B(), it is B in A? – Learn Programming Jan 04 '19 at 12:03
  • The `a` variable is pointing at an instance of `B` (Male). But it is treating it as an instance of `A` (Person). So, if you are using shadowing (like you are in your code) then you will invoke methods defined in the `A` class. – mjwills Jan 04 '19 at 12:39

3 Answers3

2

Because you are missing the glaring warning in the IDE

Severity Code Description Project File Line Suppression State Warning CS0108 'B.SomeMethod()' hides inherited member 'A.SomeMethod()'. Use the new keyword if hiding was intended.

Compiler Warning (level 2) CS0108

'member1' hides inherited member 'member2'. Use the new keyword if hiding was intended.

A variable was declared with the same name as a variable in a base class. However, the new keyword was not used. This warning informs you that you should use new; the variable is declared as if new had been used in the declaration.

If you want to hide it, use the new keyword

However, if you want to call it then use virtual and override it, or just change the method name so you are not hiding it

class A
{
   public virtual void SomeMethod()
   {
      Console.Write("This is A");
   }
}

class B : A
{
   public override void SomeMethod()
   {
      base.SomeMethod();
      Console.Write("This is B");
   }

   public void OtherMethod()
   {
      Console.Write("This is New method");
   }
}

virtual (C# Reference)

The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it:

override (C# Reference)

The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.

Polymorphism (C# Programming Guide)


In the heap in this situation when created object instance, type object pointer points to A or B?

You need not worry your self about what happens on the heap (these are implementation details), just what the language allows you to do.

However, A technically does not exist, there is only an instance of B, that has all the implementation of A (if you need it)

TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • Thanks for answer, However I want to know what is going on in the heap and implementation details are also interests me. I know that each object in the heap has sync block index and type object pointer, the second one helped JIT to determine what method to call. Where I can get implementation details of this situation ? – Learn Programming Jan 03 '19 at 23:37
  • @LearnProgramming: Read the C# and .NET specs. I've never read the .NET one, but the C# spec is surprisingly quite readable. – Flydog57 Jan 04 '19 at 00:11
0

You have to specify that you want to override a virtual function. Try this:

class A
{
    public virtual void SomeMethod()
    {
        Console.Write("This is A");
    }
}

class B : A
{
    public override void SomeMethod()
    {
        Console.Write("This is B");
    }

    public void OtherMethod()
    {
        Console.Write("This is New method");
    }
}
Ghazi
  • 126
  • 6
0

To get access to OtherMethod where it's currently failing, you need to tell your A to act like a B.

Change

a.OtherMethod();

to

(a as B).OtherMethod();
Christopher
  • 10,409
  • 13
  • 73
  • 97
  • when I have created A a = new B(), what is the object type pointer in the heap, it points to A or B type? – Learn Programming Jan 03 '19 at 23:29
  • But if it is the type of B, why the OtherMethod of B is inaccessible? – Learn Programming Jan 04 '19 at 09:29
  • 1
    Imagine `A` is a ball player and `B` is a tennis player. When you tell a `B` to "be a ball player" he'll momentarily forget he knows how to serve a tennis ball. Cast `A` as his true form, `B`, so he can serve the ball. – Christopher Jan 04 '19 at 18:16