【C#基础概念】 里氏转换-as/is

 

里氏转换

 

  1. 子类可以赋值给父类。(如果有一个地方需要一个父类作为参数,我们可以给一个子类 )

  2. 如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。

 

创建几个类帮助我们理解:

 

【C#基础概念】 里氏转换-as/is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 高山里氏转换
{
    /// <summary>
    /// 测试类
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {

        }
    }

    /// <summary>
    /// 父类
    /// </summary>
  public class Person
    {

        public void PersonSayHello()
        {
            Console.WriteLine("父类");
        }
    }

    /// <summary>
    ///  学生类继承 Person
    /// </summary>
    public class Student : Person
    {
        public void StudentSayHello()
        {
            Console.WriteLine("我是学生");
        }
    }

    /// <summary>
    ///  老师类继承 Person
    /// </summary>
    public class Teacher : Person
    {
        public void TeacherSayHello()
        {
            Console.WriteLine("老师类");
        }
    }

}
View Code

 

1.子类可以赋值给父类

在测试类中输入:

 

            // 子类可以赋值给父类:如果有一个地方需要一个父类作为参数,我们可以给一个子类代替

            // 创建一个子类对象
            //Student s = new Student();

            // 内存中就是把父类的引用 指向了 子类的对象。
            //Person p = s;
            // 简写
            Person p = new Student();

目的:如果有一个地方是一个父类作为参数,我们可以给一个子类代替就是因为子类可以赋值给父类。

例如:【C#基础概念】 里氏转换-as/is

 

 

Join(); 表示把指定的分隔符放到一个数组里面去。
可以看出 join(string separator,params object[] values); 第二个参数是 object 类型的数组,而 object 是一切类型的 父类。

 

string.Join("|", new string[] { "1", "2", "3" });
我们在这里创建的是 string 数组的对象,而这个数组属于 object 的子类。在这里正好充分说明了子类可以赋值给父类。可以输出查看:

2.如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。

在测试类中输入:

            // 如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。
            // 强转
            Student ss = (Student)p;
            ss.StudentSayHello();

            Console.ReadKey(); 

运行结果 :我是学生

说明强转成功。再将上面这段代码改为:

 

            Teacher ss = (Teacher)p;
            ss.TeacherSayHello();

            Console.ReadKey(); 

 

运行结果:

【C#基础概念】 里氏转换-as/is

 

 

这里就会发生异常,强转失败,在上面代码 Person p = new Student(); 父类中装的是 student。这两个强转充分说明了如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。
那么还有一个问题,在里氏强转时经常会抛异常,所以在我们里氏强转时经常使用 is 和 as 类型转换。
 

is 和 as

 

  • is: 表示类型转换,如果能够转换成功,则返回一个 true,否则返回一个 false 。
  • as : 表示类型转换,如果能够转换则返回对应的对象,否则返回一个 null 。

 


 

is 测试 :

 

将代码改为一下:

 

            // is 表示 将 p 转换为 Teacher,如果能够转换将在这里返回 true,否则为 false
            if (p is Teacher)
            {
                Teacher ss = (Teacher)p;
                ss.TeacherSayHello();
            } 
            else
            {
                Console.WriteLine("转换失败");
            }

 

运行结果:转化失败

可以将上面代码改为:

 

             if (p is Student)
            {
                Student ss = (Student)p;
                ss.StudentSayHello();
            } 
            else
            {
                Console.WriteLine("转换失败");
            }

 

运行结果:我是学生

as 测试 :

将上面代码注释掉,写入下面代码:

 

// as 表示如果 p 能够转换 Teacher 返回 Teacher 对象,否则返回一个 null 。
            Teacher t = p as Teacher

我们打个断点可以看出:

【C#基础概念】 里氏转换-as/is

 

返回了一个 null。换成:

 

 Student t = p as Student;

【C#基础概念】 里氏转换-as/is

 

 

知识点

  • 里氏转换多用于将子类对象作为实参传入形参为父类类型的方法中。(也就是说如果有一个地方是一个父类作为参数,我们可以给一个子类代替)

  • AS在转换的同时兼判断兼容性,IS只是做类型兼容判断,并不执行真正的类型转换。

 

 

 

 

 

 

上一篇:信号之alarm和pause函数


下一篇:【ElasticSearch】MAC(M1)安装ES流程