2

Why does testMammal.BreastFeed() called by testMammal not call the BreastFeed method of Mammals class? What is the type of testMammal? Does the left side indicate type or the right side? Mammals testMammal = (aWhale as Mammals)

using System;
using System.Collections.Generic;

namespace ConsoleApplication3
{
    class Mammals 
    {
        public string age { get; set; }
        public virtual void BreastFeed()
        {
            Console.WriteLine("This animal Breastfeeds its young ones.");
        }
    }

    class Fish : Mammals
    {
        public int FinsNum { get; set; }
        public override void BreastFeed()
        {
            Console.WriteLine("This animal Breastfeeds its young ones fish style");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Fish aWhale = new Fish();
            //Mammals testMammal = (Mammals)aWhale;

            Mammals testMammal = (aWhale as Mammals);
            testMammal.BreastFeed();
        }
    }
}
Jonathan S.
  • 5,837
  • 8
  • 44
  • 63
Athapali
  • 1,091
  • 4
  • 25
  • 48
  • 5
    A virtual function calls the most overridden function no matter what the object is cast to. If you removed the word `virtual` from the Mammals version of the function, and add `new` to the Fish definition, it'll do what you expected. – John Gibb Dec 10 '13 at 21:28
  • This comment explains it pretty well too: http://stackoverflow.com/a/18512132/99046 – John Gibb Dec 10 '13 at 21:30
  • This is great, I get a lesson in biology too. Never knew about this stuff. :) – silverbeak Dec 10 '13 at 21:31
  • Do fish have breasts though? – EkoostikMartin Dec 10 '13 at 21:31
  • 2
    Fish aren't actually mammals, and don't breastfeed. Whales are mammals, not fish. – Tim S. Dec 10 '13 at 21:32
  • o No! My analogy was so flawed! But you know where I am coming from LOL – Athapali Dec 10 '13 at 21:34
  • 1
    You may also not be aware of what is the difference between compile time type and run time type AND OR what is overriding. http://stackoverflow.com/q/846103. http://stackoverflow.com/q/4986095 – Bruno Costa Dec 10 '13 at 21:37

3 Answers3

2

Your Mammals class defines BreastFeed() as a virtual method which means that it can be overridden by its children.

The Fish class properly overrides that method with its own implementation. That means that any time you instantiate the class and treat it as Fish or Mammals, the overriden implementation will be called. That's exactly what an overriden virtual method should do.

If you defined things a little differently and hid the BreastFeed() method instead of overriding it, you would get the behavior that you're expecting.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
1

Why does testMammal.BreastFeed() called by testMammal not call the BreastFeed method of Mammals class?

testMammal is a Fish casted to a Mammals. BreastFeed() will be called on Fish

What is the type of testMammal?

Mammals

Does the left side indicate type or the right side?

Left side is the type of the variable. The object that the variable refers to can be a Mammals or any subclass.

This:

Mammals testMammal = (aWhale as Mammals);

is the same as

Mammals textMammal = new Fish(); 

The object is a Fish, the variable is of type Mammals. You can only call public members of Mammals but any overrided members will be Fish's members.

Sam Leach
  • 12,746
  • 9
  • 45
  • 73
1

It may make sense to define your BreastFeed() method in Mammals as abstract. In doing so you do not supply any implementation in the base class, which in this case is Mammals. It must be overridden in the child class or the program will not compile.

You would also define the class Mammals as abstract too.

Abstract methods are overridden in the same way as virtual methods. This may prevent confusion and would highlight any methods forgotten to be overridden by mistake.

tjheslin1
  • 1,378
  • 6
  • 19
  • 36