目录:

【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#中一些易混淆概念总结(七)---------解析抽象类,抽象方法相关推荐

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

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

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

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

  3. render在python中的含义_python面试中常见易混淆概念

    可变数据类型和不可变数据类型 基本数据类型都是不可变数据类型 数字,字符串,布尔值,元组 数据结构(容器)都是可变数据类型 列表,字典,集合 不同下划线变量的含义 _单下划线开头:弱"内部使 ...

  4. 小知识 | Java中的“魔数”

    转载自 小知识 | Java中的"魔数" 在编程过程中,我们可能经常听到"魔数"这个词,那么这个词到底指的是什么呢?什么数叫做魔数呢? 一.标识文件类型的&qu ...

  5. java常量和变量 注意事项,建议1: 不要在常量和变量中出现易混淆的字母

    第1章 Java开发中通用的方法和准则 The reasonable man adapts himself to the world;the unreasonable one persists in ...

  6. 数字电视的几个易混淆概念

      了解数字电视需要分清的五个易混淆概念 2008年北京奥运会一天天在临近,奥组委承诺北京奥运会将使用高清信号直播.为了让全国的观众收看到在自己家门口举行的这一盛大的体育赛事,广电总局已经开始在全国推 ...

  7. c语言冷门小知识,生活中的冷门小知识有哪些

    其实生活中充满了冷门知识,比如喝醋能够防止晕车.花生可以祛牙黄等等.下面是学习啦小编为大家整理的关于生活中的冷门小知识,希望大家喜欢! 生活中的冷门小知识 洗衣机强档比弱档节能 很多人没注意,在同样长 ...

  8. H.264中的一些易混淆概念

    Q:PSNR 峰值信噪比 Q:是根据它来取qp是不是? A:不是, 和QP没有直接关系, 但是QP的选择会影响到PSNR Q: 如果不用率失真最优化, 为什么选择SATD+delta×r(mv,mod ...

  9. python中函数的参数_Python小知识-Python中的函数参数(基础篇)

    0 总述 这个题目分为2篇,第一篇基本上是概念以及实例,有个相对系统的认识,第二篇想写的深入一些,不同参数类型的区别以及和c/c++的函数参数对比下异同-下面开始是第一篇的内容啦- Python中的函 ...

最新文章

  1. python 信息检索,python信息检索代码_信息检索_倒排记录表合并算法实现(python)...
  2. 移动智能家庭终端技术规范学习总结
  3. 画胖小人和瘦小人,建造者模式版本
  4. 8个超好用的Python内置函数,提升效率必备
  5. scala中的filter函数
  6. code review手记2
  7. 使用Python写一个定时锁屏软件
  8. 云计算机平台 优势,云计算平台有哪些优势
  9. Bex5登陆端口异常
  10. js实现地图四级联动
  11. wireshark数据包分析 中职网络安全
  12. 软件测试入门及实战篇
  13. android viewpager中每个view,ViewPager系列之 打造一个通用的ViewPager
  14. LightGBM综述
  15. hans wouters_Hans教学丨十大进阶长板平花招式
  16. Matlab App Designer 函数写法
  17. Docker入门笔记(1)
  18. 关于字体绘制的baseline (QT 和 D2D)
  19. Spring Boot 学习[四] web项目实战训练(增删改查,分页,排序)
  20. 利用百度云流式计算进行大规模设备监控

热门文章

  1. UpdateData函数(转)
  2. no argument specified with option /LIBPATH:错误的解决
  3. 汗!雅虎中国个人空间
  4. javascript全栈开发实践-准备
  5. 关于java.util.LinkedHashMap cannot be cast to ......的解决办法
  6. Koa2和Redux中间件源码研究
  7. 【超越白皮书3】DAG技术解析与实测
  8. form表单的action提交写到js中来,同时onclick事件也写在js中来。其action也可以通过ajax来提交的。...
  9. log4j2配置实例[按小时记录日志文件]
  10. P2P之UDP穿透NAT的原理