---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
里式转换原则的学习通过学习,掌握了里式转换原则。
里式转换原则
(1)子类可以直接赋值给父类
(2)父类可以强制类型转换为“对应”的子类
里式转换原则的存在价值就是用来实现多态
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 里氏转换原则
{
class Program
{
static void Main(string[] args)
{
Chinese c1 = new Chinese();//创建一个 Chinese 对象
c1.Name = "Mr Lucky";
Person p1 = c1;//子类直接赋值给父类
}
}
class Person//定义一个Person类 所有类的父类
{
string name;//定义一个 name 字段
public string Name
{
get { return name; }
set { name = value; }
}
}
class Chinese : Person//定义一个类,中国人 继承自Person类
{
public void SayHello()
{
Console.WriteLine("你好,我是中国人!");
}
}
class American : Person//定义一个类,美国人 继承自Person类
{
public void SayHello()
{
Console.WriteLine("你好,我是美国人!");
}
}
class Japanese : Person//定义一个类,日本人 继承自Person类
{
public void SayHello()
{
Console.WriteLine("你好,我是日本人!");
}
}
}
我们创建了一个 Person 父类,后面分别写了3个子类,都继承自 Person 类,接着,在主方法中创建了一个 Chinese 类的对象,并将继承自父类的字段 name 赋值,最后,直接将创建好了的对象 c1 赋值给 Person 类,
也就是直接将子类直接赋值给父类,调试代码发现,没有任何错误,这也就实现了里氏转换原则中的 “子类可以直接赋值给父类”。
我们创建了三个子类,如何统一管理呢?总不能new 一个子类,然后再 Person p=XX XX,这样很麻烦,我们还可以用数组将他们统一起来:static void Main(string[] args)
{
Chinese c1 = new Chinese();
c1.Name = "幸运先生";
American a1 = new American();
a1.Name = "Mr lucky";
Japanese J1 = new Japanese();
J1.Name = "にねのせ";
Person[] per = { c1,a1,J1};
}
现在,我们将 Chinese 类, American 类, Japanese 类都赋给了 Person 类,那么,现在这三个子类是什么类型的呢?在这里,三个子类就是 Person 类型的了。
还要和大家说明的是,父类只能访问父类的成员,我们看图:
在里氏转换原则第一条当中,子类直接可以赋值给父类,所以可以直接将 c1、a1、J1 存入 person类型 的数组当中,首先我们知道 Person[0] 代表的是 Chinese 类,也就是 c1 ,此时的 c1 因为直接赋值给了父类,所以是 Person 类型,也就造成了我们在用 per[0] 点的时候,只点出了 name 字段的属性 Name,而 Chinese 中的 SayHello() 方法是无法点出来的,这也就是我刚才说的,父类只能访问父类的成员。
但是我现在就想调用子类中 SayHello(),怎么办呢? 这就使用到了我们里氏转换原则中的第二条,指向子类的父类,可以强制转换为对应的子类。强制转换,大家应该都会吧!
看下面如何进行强制转换:
Person[] per = { c1,a1,J1};
//per[0]. 父类只能访问父类的成员 无法访问子类的成员,想要访问 可以进行强制转换 里氏原则中的第二条
((Chinese)per[0]).SayHello();
Console.ReadKey();
得到的结果:
里氏原则第二条, 指向子类的父类,可以强制转换为对应的子类,当我们进行强制转换以后,那么现在的 per[0] 就不在是 person 类型的了,而是 Chinese 类型的,所以我们可以点出 SayHello() 方法。
我把代码改一下:
(( American)per[0]).SayHello();
上面是将 per[0] 强制转换成 Chinese 类,我们发现是可以的,那么,当我改成 American 的时候,可不可以呢!调试一下:
再看一遍里氏转换原则第二点:
指向子类的父类,可以强制转换为对应的子类。
仔细看,可以强制转换为 对应 的子类,我将 对应 加粗了一下并下划线,记住:对应、对应 。
在 per[0] 这块区域中我们预存的是 Chinese 类型的对象 c1,并不是 American 类型的 a1,我们想将 per[0] 强制转换,就只能转换成 Chinese 类型,因为我们原本在 per[0]中存的就是 Chinese 类型的对象,这也遵循了里氏转换原则第二条“指向子类的父类,可以强制转换为对应的子类”,记住,对应,对应。
per[1] 、per[2] 也只能对应的强制转换成 American 类型 和 Japanese 类型。
通过以上的例题学习后我的感想
问题一 什么是强制类型转换(显示转换)
简单表达就是
double x = 123.11
int y = (int)x
问题二 哪一个是对应的子类
上面提到per[]数组是person类型,而数组中的c1是Chinese类型 //(声明(new) c1 的时候就确定了c1是 chinese类 型,由于将c1加入到person数组中,所以变成person类型)
如果要将person类强制转换成子类,必须转换成对应的子类,比如per[0]是 Chinese类型,per[1]是American类型
到目前为止,对代表复杂多态的里式转换原则,有了初步的了解,能够懂得原则中所谓的两个基础点。
需要在以后的实际操作中,巩固此知识点。
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com