zoukankan      html  css  js  c++  java
  • 泛型

    一、引言

    前面我们学过泛型集合List,非泛型集合ArrayList,了解到创建List集合的时候,需要指定类型,并且只能存储这种类型的数据,相比ArrayList能存储各种类型的数据而言,效率更高(避免了装箱拆箱)。那我们声明List<int>集合的时候,开始为何不直接设计一个ListInt类,而要设计成List<T>呢?因为List中的方法,算法其实是一样的,这样可以避免重复,并且,如果我要在List中保存自己自定义的类的对象的时候,(比如Person),无法再像开始那样,有预见性的设计出一个ListPerson类。所以需要引入泛型。

    二、泛型类

    下面看一个具体的例子:

     1 public class MyClass
     2     {
     3         public string [] Names { get; set; }
     4 
     5         public MyClass(string [] names)
     6         {
     7             this.Names = names;
     8         }
     9 
    10         public void Show()
    11         {
    12             foreach (string item in Names)
    13             {
    14                 Console.WriteLine(item);
    15             }
    16         }
    17     }
    View Code

    在控制台程序中输出数组中的元素:

     1 static void Main(string[] args)
     2         {
     3 
     4             string[] names = { "A","B","C","D"};
     5 
     6             MyClass mc = new MyClass(names);
     7             mc.Show();
     8 
     9             Console.ReadKey();
    10         }
    View Code

    现在需求改动,想把string类型的数组改成int类型的,这时候,我们只好把MyClass中和控制台中所有关于类型的地方全部改下,但是其他地方丝毫不用改。这当然可以,只是有点麻烦,有没有其他方式,不用改动MyClass中的东西呢?

    这时候可以泛型。改动后的代码如下:

     1  class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5 
     6             string[] names = { "A","B","C","D"};
     7             //MyClass<string> mc = new MyClass<string>(names);
     8 
     9             //如果要改成Int类型的数组,只要作如下改动
    10             MyClass<int> mc = new MyClass<int>(new int[] {1,2,3,4 });
    11             
    12             mc.Show();
    13 
    14             Console.ReadKey();
    15         }
    16     }
    17 
    18     public class MyClass<T>
    19     {
    20         public T [] Names { get; set; }
    21 
    22         public MyClass(T [] names)
    23         {
    24             this.Names = names;
    25         }
    26 
    27         public void Show()
    28         {
    29             foreach (T item in Names)
    30             {
    31                 Console.WriteLine(item);
    32             }
    33         }
    34     }
    View Code

    这里我们能明显看到泛型的方便了。

    三、泛型接口

     有以上的基础,看泛型接口就可以容易了,直接上代码:

    1  public interface IFlyable<T>
    2     {
    3         void Fly(T t);
    4     }
    View Code

    但是要注意:

    1.如果是实例类实现泛型接口,泛型接口必须指定泛型的类型:

    1  public class SpiderMan : IFlyable<string>
    2     {
    3         public void Fly(string t)
    4         {
    5             Console.WriteLine(t);
    6         }
    7     }
    View Code

    2.如果是泛型类,实现泛型接口的时候必须指定泛型的类型:

    1 public class SpiderMan<T> : IFlyable<T>
    2     {
    3         public void Fly(T t)
    4         {
    5             throw new NotImplementedException();
    6         }
    7     }
    View Code

    四、泛型方法

    1 public class Person
    2     {
    3         //方法后面加个<T>就是泛型方法
    4         public void Show<T>(T t)
    5         {
    6             Console.WriteLine(t);
    7         }
    8     }
    View Code

    main函数中的代码:

    1   Person p = new Person();
    2             p.Show("aaa");//方法名称后面不加<T>,编译器会根据传入的数据,自动推断
    3             p.Show<string>("aaa");//
    4             p.Show(2);
    View Code

    五、泛型委托

     首先写几委托和方法:

    1 public delegate void MDelegate(string str);
    1 public delegate void IDelegate(int i);
    2     public delegate void MDelegate(string str);
    3     public delegate void DDelegate(double d);
    View Code

    方法:

     1 static void M1(int i)
     2         {
     3             Console.WriteLine(i);
     4         }
     5 
     6         static void M2(string s)
     7         {
     8             Console.WriteLine(s);
     9         }
    10 
    11         static void M3(double d)
    12         {
    13             Console.WriteLine(d);
    14         }
    View Code

    我们要使用MDelegate这个委托只能传入方法签名一致的方法M2,如果我想调用M1,M3方法的话,必须再写两个委托,太麻烦。

    1 MDelegate m = M2;
    2             m("124");
    3 
    4             IDelegate i = M1;
    5             i(1);
    6 
    7             DDelegate d = M3;
    8             d(1.2);
    View Code

     但是改成泛型委托,情况就变得简单很多了

    1 public delegate void DynamicDelegate<T>(T t);
    View Code

    用上面泛型委托,可以调用M1,M2,M3方法,如下:

    1 DynamicDelegate<int> i = M1;
    2             i(1);
    3 
    4             DynamicDelegate<string> s = M2;
    5             s("afsd");
    6 
    7             DynamicDelegate<double> d = M3;
    8             d(1.2);
    View Code
  • 相关阅读:
    支付宝 微信支付 移动支付 网站支付 开发
    2017 开源中国评比的前100个优秀开源项目
    解决error: Your local changes to the following files would be overwritten by merge
    Spring-JDBC配置
    server library[unbound] 服务未绑定解决办法
    MyEclipse安装EGit插件方法
    使用GitHub和Eclipse进行javaEE开发步骤
    Spring-AOP
    SQL-字符串连接聚合函数
    Spring-注入外部值
  • 原文地址:https://www.cnblogs.com/wesley168/p/6782815.html
Copyright © 2011-2022 走看看