zoukankan      html  css  js  c++  java
  • 【C#小知识】C#中一些易混淆概念总结(七)---------解析抽象类,抽象方法 分类: C# 2014-02-10 01:55 1675人阅读 评论(0) 收藏

    目录:

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

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

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

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

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

    我笔记本上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();
            }
    复制代码

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

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



    毕业实习交流群:221376964。你也可以关注我的新浪微博进行交流。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    [kuangbin带你飞]专题十二 基础DP1 E
    hdu 1203 I NEED A OFFER! (01背包)
    hdu 2602 Bone Collector (01背包)
    hdu 4513 吉哥系列故事——完美队形II (manacher)
    hdu 2203 亲和串 (KMP)
    hdu 1686 Oulipo (KMP)
    hdu 1251 统计难题 (字典树)
    hdu 2846 Repository (字典树)
    hdu 1711 Number Sequence (KMP)
    poj 3461 Oulipo(KMP)
  • 原文地址:https://www.cnblogs.com/yisuowushinian/p/4715614.html
Copyright © 2011-2022 走看看