如果您必须按照您的建议进行操作,将 Feed 等方法保留为所有者而不是宠物的一部分,那么您可以利用动态绑定来调用正确的所有者方法:
using System;
class Pet { }
class Dog : Pet { }
class Cat : Pet { }
class Owner
{
public void HandlePet(Pet pet)
{
HandlePet((dynamic)pet);
}
private void HandlePet(Cat pet)
{
Console.WriteLine("Stroke the cat softly whispering Please don't scratch me.");
}
private void HandlePet(Dog pet)
{
Console.WriteLine("Stroke the dog firmly saying Who's a good boy?");
}
}
class Program
{
static void Main(string[] args)
{
var owner = new Owner();
Console.WriteLine("Handle dog first");
owner.HandlePet(new Dog());
Console.WriteLine("Handle cat second");
owner.HandlePet(new Cat());
Console.ReadKey();
}
}
输出:
先处理
狗 坚定地抚摸狗说谁是好孩子?
处理猫第二次
抚摸猫轻声耳语请不要抓我。
如果你可以避免它,那么我会将方法放在 Pet 类上,如下所示:
一种方法是让 Pet 成为一个抽象类,它具有EatFood
抽象Play
方法。Dog
和类将Cat
实现这些方法:
using System;
abstract class Pet
{
public abstract void EatFood();
public abstract void Play();
public void BrushHair()
{
Console.WriteLine("Hair brushed!");
}
}
class Dog : Pet
{
public override void EatFood()
{
Console.WriteLine("Eating dog food...");
}
public override void Play()
{
Console.WriteLine("Run around manically barking at everything.");
}
}
class Cat : Pet
{
public override void EatFood()
{
Console.WriteLine("Eating cat food...");
}
public override void Play()
{
Console.WriteLine("Randomly choose something breakable to knock over.");
}
}
class Owner
{
public void HandlePet(Pet pet)
{
pet.EatFood();
pet.Play();
pet.BrushHair();
}
}
class Program
{
static void Main(string[] args)
{
var owner = new Owner();
Console.WriteLine("Handle dog first");
owner.HandlePet(new Dog());
Console.WriteLine("Handle cat second");
owner.HandlePet(new Cat());
Console.ReadKey();
}
}
输出:
先处理狗
吃狗粮...
到处乱跑,到处乱叫。
头发刷了!
处理猫秒
吃猫粮...
随机选择易碎的东西打翻。
头发刷了!
如果您想使用访问者模式,请尝试以下代码:
using System;
public interface IPetVisitor
{
void Visit(Dog dog);
void Visit(Cat cat);
}
public interface IPetAcceptor<T>
{
void Accept(T visitor);
}
public abstract class Pet : IPetAcceptor<IPetVisitor>
{
public abstract void Accept(IPetVisitor visitor);
}
public class Dog : Pet
{
public override void Accept(IPetVisitor visitor)
{
visitor.Visit(this);
}
}
public class Cat : Pet
{
public override void Accept(IPetVisitor visitor)
{
visitor.Visit(this);
}
}
class Owner
{
// Private variable on owner class
private int HandCount = 2;
// Pet handler is an inner class so we can access the enclosing class' private member.
public class PetHandler : IPetVisitor
{
private Owner Owner;
public PetHandler(Owner owner)
{ Owner = owner; }
public void Visit(Dog dog)
{
Console.WriteLine("Pet the dog with {0} hands", Owner.HandCount);
}
public void Visit(Cat cat)
{
Console.WriteLine("Pet the cat with {0} hands", Owner.HandCount);
}
}
private PetHandler PetHandlerInstance;
public Owner()
{
PetHandlerInstance = new PetHandler(this);
}
public void HandlePet(IPetAcceptor<IPetVisitor> pet)
{
pet.Accept(PetHandlerInstance);
}
}
class Program
{
static void Main(string[] args)
{
var owner = new Owner();
Console.WriteLine("Handle dog first");
owner.HandlePet(new Dog());
Console.WriteLine("Handle cat second");
owner.HandlePet(new Cat());
Console.ReadKey();
}
}