里氏转换

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

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

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

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("老师类");
}
} }

1.子类可以赋值给父类

在测试类中输入:

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

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

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

例如:

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();

运行结果:

这里就会发生异常,强转失败,在上面代码 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


我们打个断点可以看出:

返回了一个 null。换成:

 Student t = p as Student;

知识点

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

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

【C#基础概念】 里氏转换-as/is的更多相关文章

  1. 20151024_004_C#基础知识(C#中的访问修饰符,继承,new关键字,里氏转换,is 和 as,多态,序列化与反序列化)

    1:C#中的访问修饰符 public: 公共成员,完全公开,没有访问限制. private: 私有的,只能在当前类的内部访问. protected: 受保护的,只能在当前类的内部以及该类的子类中访问. ...

  2. c#基础 里氏转换

    1.里氏转换1).子类可以赋值给父类2).如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象. 2.子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员. //// 1.里氏转换 ...

  3. 理解 angular2 基础概念和结构 ----angular2系列(二)

    前言: angular2官方将框架按以下结构划分: Module Component Template Metadata Data Binding Directive Service Dependen ...

  4. JavaBean 基础概念、使用实例及代码分析

    JavaBean 基础概念.使用实例及代码分析 JavaBean的概念 JavaBean是一种可重复使用的.且跨平台的软件组件. JavaBean可分为两种:一种是有用户界面的(有UI的):另一种是没 ...

  5. JavaScript随笔记(一)基础概念以及变量类型

    一.JavaScript中的基础概念 1.defer属性 一般我们在引用外部js文件的时候往往是将引用文件的位置放在标签当中,比如那么在标签中引入多个js文件时,浏览器会按照引入顺序加载执行这些引入的 ...

  6. Hadoop基础概念介绍

    基于YARN的配置信息, 参见: http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-yarn/ hadoop入门 - 基础概念 ...

  7. UML基础概念(转)

    UML基础概念 UML概述 uml简介 uml(unified Modeling Language )为面向对象软件设计提供统一的.标准的.可视化的建模语言.适用于描述以用例为驱动,以体系结构为中心的 ...

  8. 初识webpack——webpack四个基础概念

    前面的话 webpack是当下最热门的前端资源模块化管理和打包工具.它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源.当webpack处理应用程序时,它会递归地构建一个依赖关系图表 ...

  9. JavaWeb开发技术基础概念回顾篇

    JavaWeb开发技术基础概念回顾篇 第一章 动态网页开发技术概述 1.JSP技术:JSP是Java Server Page的缩写,指的是基于Java服务器端动态网页. 2.JSP的运行原理:当用户第 ...

随机推荐

  1. Vue框架怎么使用mediainfo.js来检测视频文件是否有音轨?

    啥是MediaInfo? 简而言之,MediaInfo是一个能读取音频和视频文件并分析和输出音视频信息的工具,能输出的内容包括视频信息,音轨,字幕等. MediaInfo也可以在web端使用,需要使用 ...

  2. django_templates模板与html页

    新建应用 上一篇通过"django-admin startproject helloworld"是创建项目,一个项目下可以有多个应用(app).打开cmd,cd到manage.py ...

  3. Nginx代理常用参数

    目录 一:Nginx代理常用参数 1.添加发往后端服务器的请求头信息 二:参数案例 1.lb01配置文件 2.web01 web02 web服务器 3.测试 4.重启 5.DNS域名解析 6.网址测试 ...

  4. 从容器中获取宿主机IP地址

    背景: docker 中的程序需要连接外部的程序,连接的过程中会告知外部程序自己的ip地址,然后外部的程序会回连docker中的程序.由于docker使用的是rancher中的托管模式,外部程序是没办 ...

  5. 一劳永逸,解决.NET发布云服务器的时区问题

    国内大多数开发者使用的电脑,都是使用的北京时间,日常开发的过程中其实并没有什么不便:不过,等遇到了阿里云等云服务器,系统默认使用的时间大多为UTC时间,这个时候,时区和时间的问题,就是不容忽视的大问题 ...

  6. C#运算符重载---逐步地分析与理解

    1.什么是运算符重载 定义:(百科定义)就是把已经定义的.有一定功能的操作符进行重新定义,来完成更为细致具体的运算等功能.操作符重载可以将概括性的抽象操作符具体化,便于外部调用而无需知晓内部具体运算过 ...

  7. 微信、QQ添加Universal Link

    官方说明 1. Universal Links是什么 Universal Links(通用链接),是苹果在iOS9之后,提供的一种"可通过传统HTTP链接来跳转APP"的能力. 该 ...

  8. Tomcat下 session 持久化问题(重启服务器session 仍然存在)

    感谢大佬:https://www.iteye.com/blog/xiaolongfeixiang-560800 关于在线人数统计,大都使用SessionListener监听器实现. SessionLi ...

  9. 判断一个js变量是否为数组

    今天小编给大家整理些关于javascript判断变量是否是数组(Array)的相关知识,主要通过以下四点给大家展开话题,具体内容如下所示: 1. typeof真的那么厉害吗?? //首先看代码 var ...

  10. Python多线程并发的误区

    由于项目要做一个并发测试,由于断言的东西较多,决定手写脚本.于是用python写了脚本: def test_method(thread_no): print("%s===test_metho ...