c# 泛型

来源:互联网 发布:pxe网络装机 编辑:程序博客网 时间:2024/06/05 17:21
             /*接口
             * 用来声明某些函数
             * 基本结构
             * public interface name
             * {
             *      void name(param);
             * }
             * 接口只能包含方法,属性,索引器,和事件声明,
             * 当一个类声明了接口,就必须实现这个接口下所有的方法,接口可以被多个不同的类声明,实现。
             * 接口可以集成接口,派生类接口被一个类声明时,该类需要实现这个派生类接口以及父类接口的所有方法
             * 
             * 泛型 类似于一个模子,
             * 为什么使用泛型。泛型性能更加友好,类型更加安全,易于维护,修改。
             * 例如 var list = new List();(未使用泛型)
             *   int i1 = (int)list[0]; 需要拆箱
             *   
             *     var list = new List<int>() 泛型定义为INT
             *     int l1 = list[0]l    不需要拆箱
             *     
             *  其次,如果不设定泛型,第一个例子中的数组可以插入各种类型例如string 和类对象等
             *  如果设定了泛型,数组就无法插入除开泛型以外的类型
             *  
             *  命名规则,以T开头,如果只用了一个泛型参数,可以直接命名为T。
             *  如public class list <T>
             *  -------------(简单理解,就是定义的时候,先一个T,作为一个标识符,到时候的时候再参照约束条件,确定写入类型)--------------
             *  
             * 泛型方法
             * 就是方法的模型,给定具体的类型,就可以实例化出一个操作该类的具体方法,泛型类中一般有泛型方法,普通类中也可以有泛型方法
             * 
             * 约束,添加了约束,才能更加准确的调用方法,没有约束只能调用object的方法
             * 约束的类型
             *  类名 , class, struct ,接口名,new()
             *  如果传入一个类,那就只能使用该类或者集成该类的派生类
             *  如果传入一个class 那就说明可以是任何类
             *  如果传入一个struct 说明可以传入任何值
             *  如果传入的接口名,说明可以传入该接口类型或者任何实现该接口的类型
             *  如果传入new(),说明可以传入带有 无参共有构造函数的类
             *  约束规则
             *  A 主约束 B 接口约束 C 构造约束
             *  A 只能有一个,类名,class,struct
             *  B 能有任意多个
             *  例如
             *   void cage<T>
             *        where T: Pet ,interface,new()
             *        表示pet及其派生类,必须实现interface接口, 有默认构造函数
             *  
             *  
             *  泛型接口
             *  允许我们将接口成员的参数和返回类型设置为泛型
             *  
             *  interface Imyself<T>
             *  {
             *      T Myself(T self);
             *  }
             *  
             *  协变与抗变
             *  参数类型是协变得,如果有两个类,A派生自B,那么要求B类型的参数,可以填写A
             *  方法类型是抗变得,如果一个方法返回 B, 那么返回类型只能是B ,不能是A,因为A 不一定是B,
             *                   但是如果一个方法返回是 A ,那么返回类型 可以为A也可以为B。
             *   泛型接口使用OUT关键词就表示返回类型只能是T
             *   如果使用IN关键字就表示T只能作为参数输入
             *  

             */


//代码示例

  static void Main(string[] args)
        {
             //插入类
            var dogCage = new Cage<Dog>(1);
            dogCage.Putint(new Dog("a"));
            dogCage.Putint(new Dog("b"));


            var pet = dogCage.Takeout();
            pet.printName();
            //插入数字
            var numCage = new Cage<int>(2);
            numCage.Putint(5);
            numCage.Putint(7);
            numCage.Putint(9);


            var nu = numCage.Takeout();
            Console.WriteLine("take out "+nu.ToString());


            //泛型方法举例 定义见dog类
            var dog = new Dog("D");
            dog.isHappy<person>(new person());
            dog.isHappy<int>(6);


            //泛型约束方法举例 定义见dog类
            var dogE = new Dog("E");
            dogE.isSad<Cat>(new Cat("Tom"));
            //dogE.isSad<int>(8); //这里会报错,因为约束泛型只能是pet及其派生类


            //泛型接口使用
            Program gg = new Program();
            gg.Act(new Dog("logan"));
            gg.Act(new Cat("laola"));
        }


        //接口实现
        public void Act(Dog pet)
        {
            pet.printName();
        }


        public void Act(Cat pet)
        {
            pet.printName();
        }

    }//泛型类
    public class Cage<T>
    {
        T[] array;
        readonly int Size;
        int num;

        public Cage(int n)
        {
            Size = n;
            num = 0;
            array = new T[Size];
        } 

        public void Putint(T pet)
        {
            if (num < Size)
            {
                array[num++] = pet;
                Console.WriteLine("get the pet");
            }
            else
            {
                Console.WriteLine("cage is full");
            }
        }
        public T Takeout()
        {
            if (num > 0)
            {
                return array[--num];
            }
            else
            {
                Console.WriteLine("cage is empty");
                return default(T);
            }
        }
    }
    //接口
    public interface IDog<T> where T : Pet
    {
        void Act(T pet);
    }


//pet 类

   public class Pet
    {
        private string name;
        public Pet(string name)
        {
            Name = name;
        }
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }


        virtual public void speak()
        {
            Console.WriteLine("pet speaks");
        }
        virtual public void printName()
        {
            Console.WriteLine("My name is "+Name);
        }
    }

//继承自pet类的dog类

    class Dog:Pet
    {
        public Dog(string name) : base(name)
        {
            Name = name;
        }


        public override void speak()
        {
            Console.WriteLine("Dog speaks wang wang");
        }
        //泛型方法
        public void isHappy<T>(T target)
        {
            Console.WriteLine("Dog is happy to "+target.ToString());
        }
        //泛型方法+约束
        public void isSad<T>(T target) where T: Pet
        {
            Console.Write("Dog is sad to ");
            target.printName();
        }
    }
    class Labrador : Dog
    {
        public Labrador(string name) : base(name)
        {
            Name = name;
        }
    }

//继承自pet类的cat类

 class Cat:Pet
    {
        public Cat(string name) : base(name)
        {
            Name = name;
        }
        public override void speak()
        {
            Console.WriteLine("cat speaks miao miao");
        }
    }

代码可以在github上下载:https://github.com/lcxxxc/UWP_Readness 

选择study_day3_part_two 的那一份


0 0