I can think of a couple ways you could implement something like the above.
1. Use Interfaces
If you can modify the original source code, this is probably the best option. Easy to implement, easy to maintain.
public interface IDoSomething
{
void DoSomething();
}
public class Dog : Animal, IDoSomething
{
public void Bark()
{
}
void IDoSomething.DoSomething(){
Bark();
}
}
public class Cat : Animal, IDoSomething
{
public void Meow()
{
}
void IDoSomething.DoSomething(){
Meow();
}
}
If you don't have access to the original source code, adapters may be the only option. You could use them to "synchronize" the the way your code accesses your Cat and Dog classes. You can still work with the adapter as if it were the original object, but with a modified interface that better fits the needs of your new code. It would be fairly simple to create a factory to create the appropriate adapter based on parent type.
public IDoSomething
{
void DoSomething()
{
}
}
public DoSomethingFactory
{
public static IDoSomething( Animal parent )
{
if ( typeof( parent ) is Dog )
return new DoSomethingDog( parent as Dog );
if ( typeof( parent ) is Cat )
return new DoSomethingCat( parent as Cat );
return null;
}
}
public DoSomethingDog : Dog, IDoSomething
{
Dog _parent;
public DoSomethingDog( Dog parent )
{
_parent = parent;
}
public void DoSomething()
{
_parent.Bark();
}
}
public DoSomethingCat : Cat, IDoSomething
{
Cat _parent;
public DoSomethingCat( Cat parent )
{
_parent = parent;
}
public void DoSomething()
{
_parent.Meow();
}
}
Aside from these two obvious implementations, you might want to consider these:
Use Decorators to enhance the capabilities of your classes dynamically. (Similar to the "wrapper" approach above, but baked into the class structure a little more cleanly.)
Implement a series of Command objects that your classes could handle dynamically:
cat.Do( new MakeNoiseCommand() ); // Handled as "meow"
dog.Do( new MakeNoiseCommand() ); // Handled as "bark"
Allow something similar to a Mediator to forward the requests based on the Animal's type, etc:
public class AnimalMediator
{
public void MakeNoise( Animal animal )
{
if ( typeof( animal ) is Dog ) (animal as Dog).Bark();
else if ( typeof( animal ) is Cat ) (animal as Cat).Meow();
}
}
BarkandMeowmethods, perhaps called[MakeNoise]that would allow for different method names.