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()