我的示例程序如下;
public class Animal
{
public virtual string MakeSound()
{
return "General Sound";
}
}
public class Dog : Animal
{
public override string MakeSound()
{
return "Bow..Bow..";
}
}
}
static void Main(string[] args)
{
Animal obj1 = new Animal();
Console.WriteLine("General Animal's sound id " + obj1.MakeSound());
Dog obj2 = new Dog();
Console.WriteLine("Dog Animal's sound id " + obj2.MakeSound());
//Violate LSP
Animal obj3 = new Dog();
Console.WriteLine("Animal's sound id " + obj3.MakeSound());
Console.ReadKey();
}
这里作为我的理解当我们像obj3一样为Animal创建Dog实例时,我们违反了LSP。请证实我的理解。如果是,请告诉我如何在这种情况下实现更好地理解。我认为我的编码在概念上是正确的
答案 0 :(得分:0)
你没有违反Liskov的替代规则。
Liskov轻松英语中的替换规则 - >如果Base.Method
留下任何不变量,那么Derived.Method
必须知道这些不变量。
invariant是一个对象的状态,它不会因方法执行而改变。
例如:
public class MyInt{
private int num1 = 5;
public void print(){
Console.write(num1);
}
public void increment(){
num1++;
}
}
此处,print
的不变量仅为num1
,因为它不会更改。 increment
的不变量为非,因为它会更改所有MyInt
成员。
在你的例子中:
Animal.MakeSound
具有的不变量:非。
Dog.MakeSound
具有的不变量:非。
Animal.MakeSound
中隐含Dog.MakeSound
的不变量,因此Liskov替换规则不会被破坏。
答案 1 :(得分:0)
您的示例并未真正违反LSP。我认为违规的一个更好的例子就是
public class Bird
{
public virtual void Fly(int height);
}
public class Penguin : Bird
{
public virtual void Swim(int depth);
}
public static class BirdExtensions
{
public static void Fly(this Bird bird)
{
}
}
如果我将Penguin的一个实例传递给这个方法,我可能不得不抛出运行时异常或其他东西,因为我的企鹅不会飞:(
你看到我们对基类做了一个假设(所有的鸟都可以飞),但是现在我们有一个不符合这个假设的子类的例子(企鹅不会飞)。
此外,因为Penguin
是一个Bird
,它有Fly(height=10)
的方法,所以我在技术上可以做类似的事情,
Bird b = new Penguin();
b.Fly(height=100);
b.Swim(depth=20);
这违反了企鹅的能力(他不能飞得那么高,他只能飞到0,也许......?)。