【C#小知识】C#中一些易混淆概念总结(七)---------解析抽象类,抽象方法
目录:
【C#小知识】C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用
【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举
【C#小知识】C#中一些易混淆概念总结(三)--------结构,GC回收,静态成员,静态类
【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine()
【C#小知识】C#中一些易混淆概念总结(五)---------深入解析C#继承
【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法
-----------------------------------------分割线----------------------------------------------
我笔记本上C#方面的知识基本上整理的差不多了,所以这个关于《C#小知识》的系列估计就要完结了,这个过程中谢谢大家一直来对于我的支持,你们给我的宝贵的意见对我帮助很大。
在介绍抽象类和抽象方法之前还是先提一下多态的基本概念。
其实在上一篇关于里氏替换原则就已经说明了多态的精髓“子类对象可以替换父类对象的位置,而程序的功能不受影响”。还是来看一段代码吧:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/// <summary>
/// Create By:ZhiQiang
/// Create Time:2014-2-9
/// </summary>
class Person
{
//定义虚方法以备子类重写,当子类替换父类对象的位置时,可以表现出多态
public virtual void Run()
{
Console.WriteLine( "我是人,我会跑!" );
}
public virtual void Say()
{
Console.WriteLine( "我是人,我会说话!" );
}
}
|
子类的代码如下:
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
|
//定义Teacher类继承Person
class Teacher:Person
{
public override void Run()
{
Console.WriteLine( "我是老师,我必须慢速跑" );
}
public override void Say()
{
Console.WriteLine( "我是老师,我得说表扬的话!" );
}
}
//定义Student类继承Person
class Student : Person
{
//子类重写了父类的虚方法
public override void Run()
{
Console.WriteLine( "我是学生,我会加速跑!" );
}
public override void Say()
{
Console.WriteLine( "我是学生,我会说英语!" );
}
}
|
下面需要一个实现多态的类,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//实现多态的类
class FeatureHuman
{
/// <summary>
/// 这个方法就提现了多态,当传入的是子类的对象的时候,p指向的是子类对象,就可以调用子类重写父类方法后的方法
/// </summary>
/// <param name="p">父类或者子类对象</param>
public void OutPutFeature(Person p)
{
p.Run();
p.Say();
}
}
|
主体代码和实现多态的方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
static void Main( string [] args)
{
FeatureHuman fea = new FeatureHuman();
//人的特点
Person p = new Person();
Program pro = new Program();
fea.OutPutFeature(p);
//学生的特点
Student s = new Student();
fea.OutPutFeature(s);
//老师的特点
Teacher t = new Teacher();
fea.OutPutFeature(t);
Console.ReadKey();
}
|
运行,打印结果如下:
这里可以发现,我们outputFeature方法根据传入的实体对象不同(父类变量指向了子类的对象),而打印出了不同人物的特点,这就是多态。
代码图解如下:
多态总结如下:
二,抽象类和抽象方法
在C#中使用abstract关键字修饰的类和方法,叫做抽象类和抽象方法。
1)抽象类中可以拥有没抽象成员,为了继承给他的子类调用 (抽象类就是为了定义抽象成员,继承给子类去实现,同时子类也可以调用父类的非抽象成员)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
abstract class Person
{
//private int nAge;
//abstract string strName;
//抽象类可以包含不抽象的成员,可以给继承的子类使用
public void Say()
{
Console.WriteLine( "我是父类,我是人!" );
}
public virtual void Sing()
{
Console.WriteLine( "我是父类,我是人,我可以唱歌!" );
}
//Run的抽象方法
public abstract void Run();
}
|
2)抽象类中可以有virtual修饰的虚方法
如上面的代码,在抽象类中定义了virtual修饰的方法,编译通过。抽象类就是为了定义抽象成员,继承给子类去实现,所以子类也可以实现抽象类中的虚方法。
3)抽象类不能实例化,因为有抽象成员,而抽象成员没有方法体,如下图,
4)抽象成员不能私有,如果私有子类没有办法访问
我们可以在抽象类中定义私有成员,但是没有意义。因为子类根本访问不到这些私有成员,而抽象类本身也不能实例化,所以私有成员访问不到。
5)子类必须重写父类的抽象方法
在上面代码的基础上,我们定义一个Student类,继承抽象类,但是不实现抽象类的抽象方法,编译报错。代码如下:
6)在子类中没有办法通过base关键字调用父类抽象方法
原理同上,抽象类的抽象发放没有实现语句,就算调用也没有意义。但是可以使用base关键字调用非抽象方法,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class Program
{
static void Main( string [] args)
{
//Person p = new Person();
Student s = new Student();
s.Run();
Console.ReadLine();
}
}
class Student : Person
{
public override void Run()
{
base .Say();
Console.WriteLine( "我是学生,继承了父类,我可以跑!" );
}
}
|
打印结果如下:
抽象类思维导图总结如下:
抽象方法
1)抽象方法必须定义在抽象类中,
1
2
3
4
5
6
7
8
9
|
class Student : Person
{
public abstract void Swiming();
public override void Run()
{
base .Say();
Console.WriteLine( "我是学生,继承了父类,我可以跑!" );
}
}
|
代码编译会报错,如下图:
2)抽象方法必须使用关键字修饰,示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
abstract class Person
{
//private int nAge;
//abstract string strName;
//抽象类可以包含不抽象的成员,可以给继承的子类使用
public void Say()
{
Console.WriteLine( "我是父类,我是人!" );
}
public virtual void Sing()
{
Console.WriteLine( "我是父类,我是人,我可以唱歌!" );
}
//Run的抽象方法,不能有方法体,留给子类实现
public abstract void Run();
|
抽象方法思维导图总结如下:
那么什么时候使用抽象类呢?
①子类必须重写父类的方法(相当于定义了一个标准,规范)
②父类没有必要实例化,就用抽象类
③抽象类是为了继承,为了多态
最后来看一个示例代码:
定义一个抽象类,其中包含抽象方法Run()
1
2
3
4
|
abstract class Person
{ //Run的抽象方法,只要是继承我的子类都要实现这个方法
public abstract void Run();
}
|
分别定义两个子类,继承抽象类Person
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class Student : Person
{
//public abstract void Swiming();
public override void Run()
{
// base.Say();
Console.WriteLine( "我是学生,继承了父类,我可以跑!" );
}
}
class Worker:Person
{
public override void Run()
{
Console.WriteLine( "我是工人,继承了父类,我每天在厂区跑!" );
}
}
|
为了表现多态,我们编写一个方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//该方法变现了多态,根据需要返回子类的对象
public static Person GetEntity( string str)
{
if (str== "学生" )
{
return new Student();
}
else if (str== "工人" )
{
return new Worker();
}
return null ;
}
|
main函数中的代码如下:
1
2
3
4
5
6
7
|
static void Main( string [] args)
{
//不直接实例化父类对象,只是声明一个父类对象的变量来接收方法的返回值
Person p = GetEntity(Console.ReadLine());
p.Run();
Console.ReadLine();
}
|
运行,分别输入“工人”和“学生”的打印结果如下:
到这里这一部分的内容就结束了,希望大家多多提宝贵的意见。
本文转自yisuowushinian 51CTO博客,原文链接:http://blog.51cto.com/yisuowushinian/1357647,如需转载请自行联系原作者
【C#小知识】C#中一些易混淆概念总结(七)---------解析抽象类,抽象方法相关推荐
- 【C#小知识】C#中一些易混淆概念总结(三)---------结构,GC,静态成员,静态类...
目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) ---------------------------------------分割线----------- ...
- C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用...
这几天一直在复习C#基础知识,过程中也发现了自己以前理解不清楚和混淆的概念.现在给大家分享出来我的笔记: 一,.NET平台的重要组成部分都是有哪些 1)FCL (所谓的.NET框架类库) 这些类是微软 ...
- render在python中的含义_python面试中常见易混淆概念
可变数据类型和不可变数据类型 基本数据类型都是不可变数据类型 数字,字符串,布尔值,元组 数据结构(容器)都是可变数据类型 列表,字典,集合 不同下划线变量的含义 _单下划线开头:弱"内部使 ...
- 小知识 | Java中的“魔数”
转载自 小知识 | Java中的"魔数" 在编程过程中,我们可能经常听到"魔数"这个词,那么这个词到底指的是什么呢?什么数叫做魔数呢? 一.标识文件类型的&qu ...
- java常量和变量 注意事项,建议1: 不要在常量和变量中出现易混淆的字母
第1章 Java开发中通用的方法和准则 The reasonable man adapts himself to the world;the unreasonable one persists in ...
- 数字电视的几个易混淆概念
了解数字电视需要分清的五个易混淆概念 2008年北京奥运会一天天在临近,奥组委承诺北京奥运会将使用高清信号直播.为了让全国的观众收看到在自己家门口举行的这一盛大的体育赛事,广电总局已经开始在全国推 ...
- c语言冷门小知识,生活中的冷门小知识有哪些
其实生活中充满了冷门知识,比如喝醋能够防止晕车.花生可以祛牙黄等等.下面是学习啦小编为大家整理的关于生活中的冷门小知识,希望大家喜欢! 生活中的冷门小知识 洗衣机强档比弱档节能 很多人没注意,在同样长 ...
- H.264中的一些易混淆概念
Q:PSNR 峰值信噪比 Q:是根据它来取qp是不是? A:不是, 和QP没有直接关系, 但是QP的选择会影响到PSNR Q: 如果不用率失真最优化, 为什么选择SATD+delta×r(mv,mod ...
- python中函数的参数_Python小知识-Python中的函数参数(基础篇)
0 总述 这个题目分为2篇,第一篇基本上是概念以及实例,有个相对系统的认识,第二篇想写的深入一些,不同参数类型的区别以及和c/c++的函数参数对比下异同-下面开始是第一篇的内容啦- Python中的函 ...
最新文章
- python 信息检索,python信息检索代码_信息检索_倒排记录表合并算法实现(python)...
- 移动智能家庭终端技术规范学习总结
- 画胖小人和瘦小人,建造者模式版本
- 8个超好用的Python内置函数,提升效率必备
- scala中的filter函数
- code review手记2
- 使用Python写一个定时锁屏软件
- 云计算机平台 优势,云计算平台有哪些优势
- Bex5登陆端口异常
- js实现地图四级联动
- wireshark数据包分析 中职网络安全
- 软件测试入门及实战篇
- android viewpager中每个view,ViewPager系列之 打造一个通用的ViewPager
- LightGBM综述
- hans wouters_Hans教学丨十大进阶长板平花招式
- Matlab App Designer 函数写法
- Docker入门笔记(1)
- 关于字体绘制的baseline (QT 和 D2D)
- Spring Boot 学习[四] web项目实战训练(增删改查,分页,排序)
- 利用百度云流式计算进行大规模设备监控
热门文章
- UpdateData函数(转)
- no argument specified with option /LIBPATH:错误的解决
- 汗!雅虎中国个人空间
- javascript全栈开发实践-准备
- 关于java.util.LinkedHashMap cannot be cast to ......的解决办法
- Koa2和Redux中间件源码研究
- 【超越白皮书3】DAG技术解析与实测
- form表单的action提交写到js中来,同时onclick事件也写在js中来。其action也可以通过ajax来提交的。...
- log4j2配置实例[按小时记录日志文件]
- P2P之UDP穿透NAT的原理