目录:

【C#小知识】C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用

【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举

【C#小知识】C#中一些易混淆概念总结(三)--------结构,GC回收,静态成员,静态类

【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine()

【C#小知识】C#中一些易混淆概念总结(五)---------深入解析C#继承

【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法

-----------------------------------------分割线----------------------------------------------

我笔记本上C#方面的知识基本上整理的差不多了,所以这个关于《C#小知识》的系列估计就要完结了,这个过程中谢谢大家一直来对于我的支持,你们给我的宝贵的意见对我帮助很大。

在介绍抽象类和抽象方法之前还是先提一下多态的基本概念。

其实在上一篇关于里氏替换原则就已经说明了多态的精髓“子类对象可以替换父类对象的位置,而程序的功能不受影响”。还是来看一段代码吧:

/// <summary>
/// Create By:ZhiQiang
/// Create Time:2014-2-9
/// </summary>
class Person
{ //定义虚方法以备子类重写,当子类替换父类对象的位置时,可以表现出多态
public virtual void Run()
{
Console.WriteLine("我是人,我会跑!");
} public virtual void Say()
{
Console.WriteLine("我是人,我会说话!");
}
}

子类的代码如下:

    //定义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("我是学生,我会说英语!");
}
}

下面需要一个实现多态的类,代码如下:

    //实现多态的类
class FeatureHuman
{
/// <summary>
/// 这个方法就提现了多态,当传入的是子类的对象的时候,p指向的是子类对象,就可以调用子类重写父类方法后的方法
/// </summary>
/// <param name="p">父类或者子类对象</param>
public void OutPutFeature(Person p)
{
p.Run();
p.Say();
}
}

主体代码和实现多态的方法如下:


 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)抽象类中可以拥有没抽象成员,为了继承给他的子类调用 (抽象类就是为了定义抽象成员,继承给子类去实现,同时子类也可以调用父类的非抽象成员)

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关键字调用非抽象方法,代码如下:

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)抽象方法必须定义在抽象类中,

 class Student : Person
{
public abstract void Swiming(); public override void Run()
{
base.Say();
Console.WriteLine("我是学生,继承了父类,我可以跑!");
}
}

代码编译会报错,如下图:

2)抽象方法必须使用关键字修饰,示例代码如下:

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

 abstract class Person
{//Run的抽象方法,只要是继承我的子类都要实现这个方法
public abstract void Run();
}

分别定义两个子类,继承抽象类Person

class Student : Person
{
//public abstract void Swiming(); public override void Run()
{
// base.Say();
Console.WriteLine("我是学生,继承了父类,我可以跑!");
}
} class Worker:Person
{ public override void Run()
{
Console.WriteLine("我是工人,继承了父类,我每天在厂区跑!");
}
}

为了表现多态,我们编写一个方法如下:

 //该方法变现了多态,根据需要返回子类的对象
public static Person GetEntity(string str)
{
if(str=="学生")
{
return new Student();
}
else if(str=="工人")
{
return new Worker();
}
return null;
}

main函数中的代码如下:

 static void Main(string[] args)
{
//不直接实例化父类对象,只是声明一个父类对象的变量来接收方法的返回值
Person p = GetEntity(Console.ReadLine());
p.Run(); Console.ReadLine();
}

运行,分别输入“工人”和“学生”的打印结果如下:

到这里这一部分的内容就结束了,希望大家多多提宝贵的意见。

【C#小知识】C#中一些易混淆概念总结(七)---------解析抽象类,抽象方法的更多相关文章

  1. 【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine() 分类: C# 2014-02-05 17:18 1060人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) [C#小知识]C#中一些易混淆概念总结(三) ------------------------------ ...

  2. 【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法 分类: C# 2014-02-08 01:53 1826人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...

  3. 【C#小知识】C#中一些易混淆概念总结(五)---------继承 分类: C# 2014-02-06 22:05 1106人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...

  4. 【C#小知识】C#中一些易混淆概念总结(五)---------深入解析C#继承

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...

  5. 【C#小知识】C#中一些易混淆概念总结(三)---------结构,GC,静态成员,静态类

    目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) ---------------------------------------分割线----------- ...

  6. 【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举 分类: C# 2014-02-03 01:24 1576人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 继上篇对一些C#概念问题进行细节的剖析以后,收获颇多.以前,读书的时候,一句话一掠而 ...

  7. C#中一些易混淆概念总结

    C#中一些易混淆概念 这几天一直在复习C#基础知识,过程中也发现了自己以前理解不清楚和混淆的概念.现在给大家分享出来我的笔记: 一,.NET平台的重要组成部分都是有哪些 1)FCL (所谓的.NET框 ...

  8. 【C#小知识】C#中一些易混淆概念总结---------数据类型存储,方法调用,out和ref参数的使用

    这几天一直在复习C#基础知识,过程中也发现了自己以前理解不清楚和混淆的概念.现在给大家分享出来我的笔记: 一,.NET平台的重要组成部分都是有哪些 1)FCL (所谓的.NET框架类库) 这些类是微软 ...

  9. 【C#小知识】C#中一些易混淆概念总结(八)---------解析接口 分类: C# 2014-02-18 00:09 2336人阅读 评论(4) 收藏

     这一篇主要来解析关于面向对象中最总要的一个概念--接口. 对于接口来说,C#是有规定使用Interface关键字来声明接口.它的声明是和类一致的.可以说接口就是一个特殊的抽象类.如下代码: cl ...

随机推荐

  1. RESTful架构概念

    本文转载自:http://www.ruanyifeng.com/blog/2011/09/restful.html 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软 ...

  2. SPSS-多重响应-频率和交叉表案例分析(问卷调查分析)

    在10.1休假前,希望跟大家讨论一下SPSS-多重响应--频率和交叉表分析,希望大家能够多提点提点 在云南电信网上营业厅做了一个关于“客户不使用电信3g业务的原因有哪些的问卷调查,问题所示: 这份问卷 ...

  3. linux下怎样用c语言调用shell命令

    C程序调用shell脚本共同拥有三种法子 :system().popen().exec系列数call_exec1.c , system() 不用你自己去产生进程.它已经封装了,直接增加自己的命令 ex ...

  4. 团队项目(第四周冲刺之二)—GG队

    项目冲刺: 队员 学号 叶尚文(队长) 3116008802 蔡晓晴 3216008808 杜婷萱 3216008809 龙剑初 3116004647 于泽浩 3116004661 (先把帅气的合照不 ...

  5. 基于Maven的S2SH(Struts2+Spring+Hibernate)框架搭建

    1. 前言 基于Maven的开发方式开发项目已经成为主流.Maven能很好的对项目的层次及依赖关系进行管理.方便的解决大型项目中复杂的依赖关系.S2SH(Struts2+Spring+Hibernat ...

  6. 自适应XAML布局经验总结 (一)原则和页面结构设计

    XAML布局回顾 Grid和StackPanel是核心布局,尤其以Grid最为重要. Grid是网格布局,XAML的设计者有可能参考了Html里的Table设计了Grid布局,但进行了改进.Html中 ...

  7. IIS 绑定 HTTPS 域名

    HTTPS为SSL安全通道,虽然并不清楚具体有什么用,但至少网站看上去比HTTP上档次,访问速度也没什么影响,所以有条件的话,还是做下,可以做噱头忽悠人. WIN2008系统 因为端口443冲突,只能 ...

  8. XML文件之创建

    1.创建XML文档对象XmlDocument doc=new XmlDocument() 2.创建XML根节点变量XmlElement xmlElement 3.判断XML文件是否已经存在 1)若存在 ...

  9. FreePascal - 如何在各个平台中安装CodeTyphon!

    安装CodeTyphon的操作系统: win10 X64 企业版 Ubuntu16.04 X64 Mac OS 10.11 虚拟机: VMware® Workstation 12 Pro 12.5.2 ...

  10. 《Python黑帽子:黑客与渗透测试编程之道》 网络:原始套接字和流量嗅探

    Windows和Linux上的包嗅探: #!/usr/bin/python import socket import os #监听的主机 host = "10.10.10.160" ...