您的位置:首页 > 编程语言 > C#

【C#基础知识点】——里氏转换-as/is

2017-04-28 20:06 260 查看

里氏转换

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

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

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

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。这两个强转充分说明了如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。

那么还有一个问题,在里氏强转时经常会抛异常,所以在我们里氏强转时经常使用 isas 类型转换。

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;




OK ! ! !

知识点

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

AS在转换的同时兼判断兼容性,IS只是做类型兼容判断,并不执行真正的类型转换。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: