多态特性
多态性可以简单的说"一个接口,多种方法",它是在程序运行的过程中才调用的方法,多态性是面向对象编程的核心概念。
多态使得子类(派生类)的实例可以直接赋值予基类的变量(这里不需要经行强制类型转换),然后就可以直接通过这个变量调用子类(派生类)的方法。多态性有什么作用呢?封装可以影藏实现细节,使得代码模块化;继承可以扩张已经存在代码快,目的就是为了代码的重用;多态则是为了实现另外一个目的接口重用,接口是消耗时间的资源,设计接口要比设计一大堆类更有效率,不过新手们就不怎么会设计接口,当然本人也是菜鸟不太会写接口(写不好或者说定义不好接口)。
多态的实现
多态性是通过子类(派生类)中重写基类的虚方法或者函数成员来实现的,下面运行一个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#基础东西,大家共同进步,如果那里有问题还请各位大虾,朋友指教!