目录:

【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. 表格边框重复合并属性: border-collapse:collapse;

    table { border-collapse:collapse; }

  2. The First Android App----Adding the Action Bar

    In its most basic form, the action bar displays the title for the activity and the app icon on the l ...

  3. C++中的数组问题

    C++中的数组问题 1. 数组赋值与初始化 (1)直接初始化: ]={,,}: (2)遍历访问初始化: ;i< ;i++) //直接读入,或者用别的数组,以及别的(i+1)等. (3)内存操作函 ...

  4. Docker搭建 MySQL 主从复制

    为什么选 Docker 搭建主从复制需要两个以上的MySQL, 使用 Docker 非常方便.如果以前没用过,找个简单的文档看看,熟悉一下命令. 搭建过程 1.下载镜像 docker pull mys ...

  5. Facebook支撑万亿Post搜索背后的技术窥探

    转自http://www.csdn.net/article/2013-10-29/2817333-under-the-hood-building-posts-search 近日,Facebook为po ...

  6. 百分之 95% 的程序员不知道 Trending 是什么。

    前言如果学习到的知识不成体系,那么遇到问题时就会非常难解决.常有人问你从哪里了解新技术怎么判断其发展趋势的,除了关注 Hacker News 以及庞大的 Awesome 还有没有其它方式?有啊当然是每 ...

  7. [调试]VS2013调试时提示“运行时当前拒绝计算表达式的值”

    VS2013 下单元测试调试时遇到的问题,以前倒从未遇到过. 中文关键字在百度和谷歌中搜索均无果. Google 下搜索 “The runtime has refused to evaluate th ...

  8. ASP.NET Core使用EF Core操作MySql数据库

    ASP.NET Core操作MySql数据库, 这样整套环境都可以布署在Linux上 使用微软的 Microsoft.EntityFrameworkCore(2.1.4) 和MySql出的 MySql ...

  9. Spring Boot项目搭建

    1.Spring Boot概述 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人 ...

  10. allowMultiQueries=true允许插入多条语句

    在context.xml中,url写成url="jdbc:mysql://localhost:3306/fivecrowdsourcing?allowMultiQueries=true&qu ...