自强不息,厚德载物!身心自在,道法自然!


多态特性

多态性可以简单的说"一个接口,多种方法",它是在程序运行的过程中才调用的方法,多态性是面向对象编程的核心概念。

       多态使得子类(派生类)的实例可以直接赋值予基类的变量(这里不需要经行强制类型转换),然后就可以直接通过这个变量调用子类(派生类)的方法。多态性有什么作用呢?封装可以影藏实现细节,使得代码模块化;继承可以扩张已经存在代码快,目的就是为了代码的重用;多态则是为了实现另外一个目的接口重用,接口是消耗时间的资源,设计接口要比设计一大堆类更有效率,不过新手们就不怎么会设计接口,当然本人也是菜鸟不太会写接口(写不好或者说定义不好接口)。

多态的实现

  多态性是通过子类(派生类)中重写基类的虚方法或者函数成员来实现的,下面运行一个demo,看看效果:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo2
{
    /// <summary>
    /// 自定义DemoClassO
    /// </summary>
    class DemoClassO
    {
        private int h = 0;      //定义变量作为加数 int
        private int t = 0;      //定义变量作为被加数 int

        //加数
        public int H
        {
            get { return h; }
            set { value = h; }
        }
        //被加数
        public int T
        {
            get { return t; }
            set { value = t; }
        }
        /// <summary>
        /// 定义一个virtual类的方法,以便在子类(派生类)中重写该方法
        /// virtual修饰符:为了经行重写,要求在基类和子类(派生类)中显式的执行一个操作。在基类中,必须将允许重写的每个具体成员标记为virtual
        /// </summary>
        /// <returns>求和</returns>
        public virtual int Add()
        {
            return H + T;
        }
    }

    /// <summary>
    /// 自定义DemoClassT并且继承DemoClassO
    /// </summary>
    class DemoClassT : DemoClassO 
    {
        /// <summary>
        /// 重写基类中的虚方法
        /// </summary>
        /// <returns>返回2个int变量的和</returns>
        public override int Add()
        {
            int h = 5;
            int t = 15;
            return h + t;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            DemoClassT demot = new DemoClassT(); //实例化DemoClassT
            /**使用子类DemoClassT的对象实例化基类DemoClassO的对象**/
            DemoClassO demoo = (DemoClassT)demot;

            demoo.H = 45;               //给DemoClassO类中的属性赋值
            demoo.T = 33;
            Console.WriteLine(demot.Add());  //调用子类(派生类)中的方法
            Console.WriteLine(demoo.Add());  //这里同样调用子类(派生类)中的方法
            Console.ReadLine();
        }
    }
}

我们DeBug下,看看效果如下图所示:

Explain :

子类(派生类)从基类继承时,它会获得基类的所以方法,字段,属性和时间。要更改基类的数据和行为,有两种选择:

1.使用新的派生成员替换基成员,或者可以重写虚拟的基成员。上面就是简单的重写了基类中的方法。

2.使用新的派生成员替换基类的成员,这是需要New关键字。

如果基类定义了一个方法,字段或属性,则new关键字用于在子类(派生类)中创建该方法,字段或者属性的新定义。new关键字放置在要替换的类成员的返回类型之前,所以上面的列子中重写基类虚方法的代码也可以替换如下形式:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo2
{
    /// <summary>
    /// 自定义DemoClassO
    /// </summary>
    class DemoClassO
    {
        private int h = 0;      //定义变量作为加数 int
        private int t = 0;      //定义变量作为被加数 int

        //加数
        public int H
        {
            get { return h; }
            set { value = h; }
        }
        //被加数
        public int T
        {
            get { return t; }
            set { value = t; }
        }
        /// <summary>
        /// 定义一个virtual类的方法,以便在子类(派生类)中重写该方法
        /// virtual修饰符:为了经行重写,要求在基类和子类(派生类)中显式的执行一个操作。在基类中,必须将允许重写的每个具体成员标记为virtual
        /// </summary>
        /// <returns>求和</returns>
        public virtual int Add()
        {
            return H + T;
        }
    }

    /// <summary>
    /// 自定义DemoClassT并且继承DemoClassO
    /// </summary>
    //class DemoClassT : DemoClassO 
    //{
    //    /// <summary>
    //    /// 重写基类中的虚方法
    //    /// </summary>
    //    /// <returns>返回2个int变量的和</returns>
    //    public override int Add()
    //    {
    //        int h = 5;
    //        int t = 15;
    //        return h + t;
    //    }
    //}

    class DemoClassT : DemoClassO 
    {
        /// <summary>
        /// 重写基类虚方法
        /// </summary>
        /// <returns>返回2个int变量的和</returns>
        public new int Add() 
        {
            int h = 5;
            int t = 15;
            return h + t;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            DemoClassT demot = new DemoClassT(); //实例化DemoClassT
            /**使用子类DemoClassT的对象实例化基类DemoClassO的对象**/
            DemoClassO demoo = (DemoClassT)demot;

            demoo.H = 45;               //给DemoClassO类中的属性赋值
            demoo.T = 33;
            Console.WriteLine(demot.Add());  //调用子类(派生类)中的方法
            Console.WriteLine(demoo.Add());  //这里同样调用子类(派生类)中的方法
            Console.ReadLine();
        }
    }
}

我们DeBug下,看看效果如下图1所示:

图1.OK先实验到这里。

 其实就在我们整天搞C#中,继承,虚方法和重写方法的组合混在一起才能实现多态性。

简单的聊下new,new也是C#的修饰符和static , override ,virtual等一样。我们经常用来实例化对象常用new,就上面new关键字用于在子类(派生类)中创建该方法来说说new在这里是怎么一回事?

     我们在子类(派生类)用new创建了一个方法,它会在基类面前隐藏重新声明的成员。这时,不是调用派生类的最远的成员,相反,基类成员就会继续搜索继承链(关系),找到使用了new修饰符的那个成员之前的成员,然后调用该成员。如果继承关系中仅包含两个类,就会使用基类中的成员,感觉就像是派生类没有重写那个成员。假如你字子类没有指定override,也没有指定new,它默认就是new,从而维护版本的安全。从C#角度看,它唯一的作用就是移除编译器的警告。

C#基础东西,大家共同进步,如果那里有问题还请各位大虾,朋友指教!

 

posted @ 2014-04-10 22:41  辉太  阅读(635)  评论(0编辑  收藏  举报

路漫漫其修远兮,吾将上下而求索!