On inheritance and polymorphism in cats and dogs (and other beasts too)
Adam D. Ruppe via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Dec 20 08:03:35 PST 2014
On Saturday, 20 December 2014 at 15:40:32 UTC, Derix wrote:
> // do what all beasts do
You'll want to call the function in the base class, which is done
with the super keyword in D.
I wouldn't make the super function return the new instance
though, that can't be as easily customized. I'd separate it into
two functions: breed and genetic mix
class Beast {
// call this on a new zygote
// it is protected because it doesn't make sense to mix
genetics
// in public
protected void mixGenetics(Beast mother, Beast father) {
// modify this to be a combination of generic traits
// for example
this.furColor = mother.furColor + father.furColor;
}
}
Now, make the specific breed functions on the subclasses. I
didn't put that in the interface because you typically don't want
to substitute parents with generic beasts - cats and dogs can't
breed together, but if there was a breed(Beast) function in the
base class, that would be permitted. (in OO theory, this is the
liskov substitution principle)
class Cat : Beast {
Cat breed(Cat sire) {
Cat offspring = new Cat();
offspring.mixGenetics(this, sire);
return offspring;
}
protected override void mixGenetics(Cat mother, Cat father) {
super(mother, father); // calls the generic
Beast.mixGenetics
// now we can do cat-specific stuff
this.pickiness = mother.pickiness * father.pickiness;
}
}
Dog would look similar to cat.
However, since mixGenetics really only makes sense when making a
new Cat, you might want to make it a constructor instead of a
method, then follow the same pattern.
> Cat class. How do I de-specialize it so it can behave as an
> instance of the more generic Beast class ? Then, the offspring
> will in turn be an instance of Beast : how to cast it as a Cat ?
Generally speaking, de-specialization happens automatically. The
super keyword calls the parent class' version which takes care of
all that.
You can cast Beasts back into Cats with cast(Cat) beast. Be sure
to check for null - if beast is a dog, that cast will return null.
> So far, all I've been able to do is to dance around the issue by
> writting ad-hoc constructors like
that makes some sense, you'd just want to make sure the specific
ones are done in specific child constructors, then call the
parent with super()
More information about the Digitalmars-d-learn
mailing list