CH08-使用虚方法实现多态
CH08-使用虚方法实现多态
本章目标
- 理解为什么要使用多态?
- 理解多态的概念
- 掌握虚方法实现多态
本章内容
1、多态概念
为什么要使用多态?
演示案例:通过第7章讲解的继承方式来实现学生和老师的自我介绍功能。
创建父类:Person
1
2
3
4
5
6public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}创建子类(学生类和老师类),实现自我介绍方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//学生类
public class Student : Person
{
public string hobby { get; set; }
public void SayHi()
{
Console.WriteLine("大家好,我叫:{0},年龄:{1},爱好:{2}",Name,Age,hobby);
}
}
//老师类
public class Teacher : Person
{
public int YearOfService { get; set; }
public void SayHi()
{
Console.WriteLine("大家好,我叫:{0},年龄:{1},教龄:{2}", Name, Age, YearOfService);
}
}测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26static void Main(string[] args)
{
//使用集合保存多个学生和老师对象,Person作为集合对象
List<Person> list = new List<Person>
{
new Teacher(){Id=1001,Name="张老师",Age=38,YearOfService=15},
new Student(){Id=100001,Name="张三",Age=16,hobby="篮球"},
new Student(){Id=100002,Name="李四",Age=17,hobby="听音乐,打游戏"}
};
//循环集合,实现自我介绍
foreach (Person person in list)
{
//通过is-a判断
if(person is Teacher)
{
Teacher teacher=(Teacher)person;
teacher.SayHi();
}
if(person is Student)
{
Student student=(Student)person;
student.SayHi();
}
}
}通过上述代码,可思考一问题:
在遍历Person集合实现问好功能时,需要用is关键字判段每个Person的类型。这时会带来一个问题,如果Person类的子类非常多,SayHi()方法各不相同,那么在程序中就要对众多的对象编写非常多的if语句进行判断,使程序变得庞大,扩展困难。
如何解决以下问题?
通过多态可以解决
多态概念:
概念:
多态: “多种形态”,指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
简单理解说明:
多态是建立在继承的基础上,同一个方法,操作于不同的对象,实现的方式不一样,则称为多态。
生活中的多态有很多,如下:
不同对象对于同一个方法(Cut)实现不同的行为:
吃饭操作:中国人吃饭用筷子,印度人吃饭用手抓,西方人吃饭用刀叉
请思考你认为生活中的多态还有那些?
在C#中实现多态的方式:
- 通过虚方法实现多态
- 通过抽象方法实现多态
2、虚方法实现多态
语法:
在父类中定义虚方法:
1
2
3
4访问修饰符 virtual 返回值类型 方法名()
{
//方法体
}注意事项:
在方法中加入关键字:virtual
在子类中重写虚方法:
1
2
3
4
5访问修饰符 override 返回值类型 方法名()
{
//方法体
}注意事项:
父类中定义的虚方法并非必须被子类重写。在父类中可给出虚方法的默认实现。如果子类不重写父类的虚方法,依然执行父类的默认实现;反之,则执行子类重写后的方法。
通过虚方法改善以上案例:
在父类中定义虚方法,实现自我介绍:
1
2
3
4
5
6
7
8
9
10
11
12
13public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
/// <summary>
/// 在父类定义虚方法
/// </summary>
public virtual void SayHi()
{
Console.WriteLine("大家好,我叫:{0},年龄:{1}", Name, Age);
}
}在子类重写父类的虚方法,通过override实现重写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class Student : Person
{
public string hobby { get; set; }
public override void SayHi()
{
Console.WriteLine("大家好,我叫:{0},年龄:{1},爱好:{2}", Name, Age, hobby);
}
}
public class Teacher : Person
{
public int YearOfService { get; set; }
public override void SayHi()
{
Console.WriteLine("大家好,我叫:{0},年龄:{1},教龄:{2}", Name, Age, YearOfService);
}
}优化测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28static void Main(string[] args)
{
//使用集合保存多个学生和老师对象,Person作为集合对象
List<Person> list = new List<Person>
{
new Teacher(){Id=1001,Name="张老师",Age=38,YearOfService=15},
new Student(){Id=100001,Name="张三",Age=16,hobby="篮球"},
new Student(){Id=100002,Name="李四",Age=17,hobby="听音乐,打游戏"}
};
//循环集合,实现自我介绍
foreach (Person person in list)
{
/*//通过is-a判断
if (person is Teacher)
{
Teacher teacher = (Teacher)person;
teacher.SayHi();
}
if (person is Student)
{
Student student = (Student)person;
student.SayHi();
}*/
person.SayHi();//直接调用父类的方法,如果子类重写了父类的虚方法,则调用子类的方法
}
}
虚方法实现多态注意事项:
- 父类定义虚方法,在方法中加入virtual关键字,子类重写虚方法使用override。
- 虚方法必须有方法体
- 子类可以重写父类的虚方法,也可以不用重写。
- 调用时,如果子类重写了父类的虚方法,那么直接调用子类的方法,否则,直接调用父类的虚方法。
方法重写和方法重载的区别:
- 方法重写:在不同的类中,方法名、参数列表、返回值一样,提供不同的实现。
- 方法重载:在同一个类中,方法名相同,参数不同,与返回类型无关。
本章总结
本章作业
通过虚方法实现多态完成学生和老师的自我介绍功能。
通过多态,实现工作汇报操作
需求说明:
- PM类和SE类均继承Employee,公共属性在父类构造函数中初始化,在父类定义DoWork()虚方法
- 实现不同员工汇报工作的DoWork()方法,重写父类的DoWork()方法
- SE通过遍历工作项,输出工作信息
- PM输出固定工作信息
多态实现计算器:
实现思路:
- 创建父类Operation
- 属性NumberA和NumberB
- 虚方法GetResult()
- 依次创建子类OpeartionAdd等,继承父类并重写虚方法GetResult()
- 实现计算响应事件
- 根据不同运算符,创建不同子类对象
- 初始化运算数并执行计算
- 创建父类Operation
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 广创科技教育-Blog!
评论