里氏替换原则的作用
- 里氏替换原则是实现开闭原则的重要方式之一。
- 它克服了继承中重写父类造成的可复用性变差的缺点。
- 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
- 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。
里式替换原则:
- 子类可以赋值给父类
- 如果父类装的是子类对象,那么可以将这个父类强制转换成子类对象。
以下代码体现了里式替换:
//里式替换原则:
//1、子类可以赋值给父类:如果有一个地方需要一个父类作为参数,我们可以给一个子类代替
//2、如果父类中装的是子类对象,那么可以将这个父类强转为子类对象
class Program
{
static void Main()
{
Person p = new Student();
//Join()的参数构成:(char separator, params object?[] values):string
//下面的string是object的子类,new string[]就体现了子类可以代替父类作为参数。所以这里体现了里式替换
string str = string.Join('|', new string[] { "1", "2", "3" });
Console.WriteLine(str); //输出结果:1|2|3
Console.WriteLine("==========================================");
Person[] pers = new Person[10]; //初始化一个Person数组
for (int i = 0; i < pers.Length; i++)
{
pers[i] = new Student(); //为数组里的每一个元素创建一个Student对象
}
for (int i = 0; i < pers.Length; i++)
{
//pers[i].PersonSayHello(); 如果是左边这句,则只会调用父类的方法,只会输出“我是父类”,因为数组是Person类的
//补充知识点:is关键字表示: 如果能够转换成功,则返回一个true,都则返回一个false
if (pers[i] is Student) //判断元素所属类型
{
((Student)pers[i]).StudentSayHello(); //通过强转才能调用Student类的方法
}
}
Console.WriteLine("==========================================");
//2、如果父类中装的是子类对象,那么可以将这个父类强转为子类对象
Student ss = (Student)p; //将父类强转成子类
ss.StudentSayHello(); //输出结果:我是学生 (转换成功)
if (p is Teacher) //如果p属于Teacher的实例
{
Teacher ss2 = (Teacher)p; //将父类强转成子类Teacher类
ss2.TeacherSayHello();
}
else
{
Console.WriteLine("转换失败,因为p里是Student类的对象,无法转成Teacher类的");
}
//补充知识点:as:如果能够转换则返回对应的对象,否则返回一个null
Student t = p as Student;
t.StudentSayHello(); //输出结果:我是学生
Teacher tt = p as Teacher;
tt.TeacherSayHello(); //输出报错,因为因为p里是Student类的对象,无法转成Teacher类的
}
}
public class Person
{
public void PersonSayHello()
{
Console.WriteLine("我是父类");
}
}
public class Student : Person
{
public void StudentSayHello()
{
Console.WriteLine("我是学生");
}
}
public class Teacher : Person
{
public void TeacherSayHello()
{
Console.WriteLine("我是老师");
}
}
整个代码输出结果:
1|2|3
==========================================
我是学生
我是学生
我是学生
我是学生
我是学生
我是学生
我是学生
我是学生
我是学生
我是学生
==========================================
我是学生
转换失败,因为p里是Student类的对象,无法转成Teacher类的
我是学生
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at Program.Main() in E:\JetBrains Rider 2022.1.2\projects\ConsoleApp1\ConsoleApp1\Program.cs:line 54
补充知识:子类对象可以调用父类的成员,但是父类对象永远都只能调用自己的成员。
本篇参考视频教程里的P120:【01_C#入门到精通】新手强烈推荐:C#开发课程,一整套课程_哔哩哔哩_bilibili
如有表述错误,恳请阅者不吝赐教,谢谢!