We have now encapsulated the fly() and quack() behaviors into their own groups of classes. Then each instance of the duck object can have their own instance or whichever behavior is appropriate to them and are contained in their FlyBehavior and QuackBehavior properties. By doing this, a duck class is not locked into a specific type of behavior and these behaviors can easily be altered at runtime. Additionally, if we suddenly add a new type of flying behavior, it is as simple as adding a new subclass to the FlyBehavior group.

download: source code

Mallard Duck
Display:
Swim: This duck is swimming.
Quack: Quack!
Fly: I'm Flying!
Redhead Duck
Display:
Swim: This duck is swimming.
Quack: Quack!
Fly: I'm Flying!
Rubber Duck
Display:
Swim: This duck is swimming.
Quack: Squeak!
Fly:
Decoy Duck
Display:
Swim: This duck is swimming.
Quack:
Fly: