我正在读一本关于设计模式的书,其中有一章是关于里氏替换原则的,它说要做到这一点(和其他任务)以实现该原则:
子类方法中的参数类型应该与超类方法中的参数类型匹配或更抽象。听起来很混乱?让我们举个例子。
假设有一个类有一个应该喂猫的方法:feed(Cat c)。
客户端代码总是将 cat 对象传递给这个方法。
◦ 好:假设您创建了一个覆盖该方法的子类,以便它可以喂养任何动物(猫的超类):feed(Animal c)。现在,如果您将这个子类的对象而不是超类的对象传递给客户端代码,一切仍然会正常工作。该方法可以喂所有 动物,所以它仍然可以喂养客户路过的任何猫。
◦ 错误:您创建了另一个子类并将喂养方法限制为仅接受孟加拉猫(猫的子类):feed(BengalCat c)。如果您将客户端代码链接到这样的对象而不是原始类,客户端代码会发生什么情况?由于该方法只能喂养特定品种的猫,它不会为客户传递的普通猫提供服务, 破坏所有相关功能。
对我来说一切似乎都很好,直到我决定尝试在 C# 中实现这个例子。
这是我为更好地理解示例的“好”部分而编写的代码:
public class Animal { }
public class Cat : Animal { }
public class AnimalFeeder
{
public virtual void Feed(Cat c)
{
Console.WriteLine("Feeding a cat...");
}
}
public class GenericFeeder : AnimalFeeder
{
public override void Feed(Animal a) // Compile Error - No suitable method found to override
{
Console.WriteLine("Feeding an animal...");
}
}
唯一的问题是我得到上面的错误,
也许我误解了这个例子,没有写正确的代码,
如果是,有人可以帮助我以正确的方式更正代码吗?
提前谢谢你!
你正在读的书是什么书?我不确定这是正确的行为,但您可以使用 shadowing 而不是覆盖以避免编译错误:
public class Animal { }
public class Cat : Animal { }
public class AnimalFeeder
{
public virtual void Feed(Cat c)
{
Console.WriteLine("Feeding a cat...");
}
}
public class GenericFeeder : AnimalFeeder
{
new public void Feed(Animal a)
{
Console.WriteLine("Feeding an animal...");
}
}