面向对象三大特性分别是封装,继承和多态,面向对象编程的主要思想就是创建对象,调用方法达到解决问题的目的.但是好多初学者在多态方面不是太理解,主要是因为有一个概念没有搞清楚,那就是里氏转换;
  具有继承关系的父类和子类进行里氏转换时要遵循以下两个原则:
1.可以把子类直接赋值给父类,即父类的位置都可以用子类来替换;
2.在上面1的基础上,可以把父类强制转换成相对应的子类;
先看如下代码:

纯文本查看  复制代码



class           Person         


                    {         


                    public           void           Talk()         


                    {         


                    Console.WriteLine(          "person talk"          );         


                    }         


                    }         


                    


                    class           Student:Person         


                    {         


                    public           void           Said()         


                    {         


                    Console.WriteLine(          "student said"          );         


                    }         


                    }



Student类继承了Person类,在Main方法中的代码如下:


纯文本查看  复制代码






public           static           void           Main(string[] args)         


                    {         


                    Person person =           new           Person();         


                    Student student =           new           Student();         


                    person.Talk();         


                    student.Talk();         


                    student.Said();         


                    }



Person类和Student类的对象都可以调各自类里面的公有成员,同时Student类的对象也可以调到其父类里面的公有方法,这是因为Student类继承了Person类.把上面的代码更改如下:


纯文本查看  复制代码





public           static           void           Main(string[] args)         


                    {         


                    


                    Student student =           new           Student();         


                    Person per = student;         


                    per.Talk();         


                    }



把子类Student的一个对象赋值给了其父类Person的对象,即父类的对象指向子类的对象,系统并没有报错,按常理来说学生是人是没有错的,从继承关系来说,子类把父类的成员继承了过来,父类对象在调用父类里面的公有成员时,仍可以调得到,功能没有任何改变.这个就是里氏转换第一原则:子类可以直接赋值给其父类,其作用是使数据达到了统一,就如系统里面提供的方法其参数是object类型一样,任何数据类型都可以传递.假如一个方法的参数是父类的类型,则在调用该方法时可以把子类的对象直接传递过来,功能不会受到影响;但是上面的代码有一个问题:把子类对象赋值给父类对象后,再调子类里面的公有成员时会调不到,那是因为per是父类的对象,其所在父类里面并没有子类里面的成员,所以调不到.想要调到子类里面的公有成员需把代码做如下更改:


纯文本查看  复制代码





public           static           void           Main(string[] args)         


                    {         


                    Student student =           new           Student();         


                    Person per = student;         


                    //第一种转换方法,强制转换         


                    Student st1 = (Student)per;         


                    //第二种转换方法,使用as         


                    Student st2 = per as Student;         


                    st1.Said();         


                    st2.Said();         


                    }



在第二行代码的基础上,把父类对象转换成子类类型,这样就可以调到子类里面的公有变量了.这就是里氏转换的第二个原则,有一点需要强调的是必须在第一个原则的基础上才可以完成转换.上面的代码用了两种转换方法,第一种是强制转换,如果转换不成功,系统会报错,第二种使用as进行转换,如果能够转换则进行转换,如果不能转换则返回null,什么也不做;


通过以上的代码我们可以总结出来里氏转换的作用:就是把不同子类的对象统一转换成其基类的类型,使数据类型达到统一,这样就可以写出一套用的代码,在基类对象所在的位置都可以传进来子类的对象,尽可能的来重用所写的代码.