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

Reply via email to