I was just going to post the same exact thing! This actually thew me off on later chapters with Interfaces.
The statement:
You can assign a variable that is of the base type to a variable of one of the derived types...
Is backwards! We're assigning a derived type TO a base type.
Your statement is better:
You can assign a variable of one of the derived types to a variable of the base type.
But i think what's going on is more like:
You can assign a REFERENCE of a derived type to a base type. (as these are reference types in C#)
This statement confused me and i wondered what exactly is happening there? Does myAnimal become myCow.. etc. Rehashing some C++ i learned a while ago, i was able to gain an understanding.
In C++ imagine you have an array of pointers of type animal:
Animal* myAnimalArray[]
Pointers are simply like variables that contain an address. In this array, you have pointers that point to various objects derived from Animal (cow, chicken, duck, etc). So when you call a function with one of these pointers, polymorphism allows the correct (derived) function to be called. Essentially, the same thing happens here in C# - we give a reference of myCow to myAnimal, so:
myAnimalArray[0] -> DoSomething(); (assuming index 0 is a pointer to a cow object)
Or maybe more simply
*myCowPointer->DoSomething(); (the myCowPointer is of type Animal)
is the same as
myAnimal.DoSomething(); (given that: myAnimal = myCow;)
In the first example, a pointer of Animal type, which is pointing to a Cow object, calls the DoSomething() function.
The -> replaces . for pointers. With polymorphism, it knows to call the overwritten function.
I think you're also correct in saying that it must be virtual and overriden in the derived class!
What i don't understand is why this is not included in the errata!?!?! The first statement is obviously incorrect!
Can the authors chime in on this?