On inheritance and polymorphism in cats and dogs (and other beasts too)
Mike Parker via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Dec 21 07:05:46 PST 2014
On Sunday, 21 December 2014 at 10:42:37 UTC, Derix wrote:
If you change the mother and father parameters from Beasts to
Cats, then you aren't overriding anything -- you are
/overloading/. That's where the first two errors were coming
from. In order for a subclass method to override a base class
method, the signature has to be the same (same parameter types).
The error about pickiness was because you were trying to access
mother.pickiness and father.pickiness even though mother and
father are declared as Beasts -- Beasts don't have pickiness. To
get at their pickiness you have to downcast them to Cats. Think
of it as a 'view' of each object.
The mother and father parameters are declared as Beasts, so you
can only "see" what a Beast has. You can't see anything that a
Cat has through a Beast, because the Beast might actually be a
Dog instead. So you have to create a new "view" by casting to the
appropriate type. If the underlying object is not an instance of
the type you cast to, the cast will return null and you can
immediately return from the function, throw an error, or whatever
you think is appropriate in that case.
class Cat : Beast
{
protected override void mixGenetics( Beast mother, Beast
father )
{
// The superclass works on Beasts, so give it the Beasts
super.mixGenetics( mother, father );
// This method needs cats, so cast to Cats
Cat catmom = cast( Cat )mother;
Cat catdad = cast( Cat )father;
// If the casts failed, then mother and father are not
Cats. Since
// they are not Cats, you can't do anything Catty with
them. So
// either return from the function or throw an Error or
something.
if( catmom is null || catdad is null )
throw new Error( "Expected cats, got something else." );
// Now do Catty things
pickiness = (mother.pickiness + father.pickiness) / 2;
}
}
You never need a cast operator to cast up and down a class
hierarchy. A Cat *is* a Beast, so you can always "upcast" without
fear of failure. A Beast *might be* a Cat, so you can attempt a
"downcast" when you must and the cast will return null if the
underlying instance isn't actually a Cat.
More information about the Digitalmars-d-learn
mailing list