泛型

   今天上午研究了一个小知识点——泛型,想分享给大家。

 

总结了一下我的研究结果:泛型——集数组和集合优点于一身的好玩意儿

 

想这样来引出泛型:通过对数组和集合的缺点分析来唤出泛型,鉴于有些同学还不会

 

(或还没用过)数组和集合,我就连数组和集合也稍稍说一下下:

 

开始啦!!!

 

       今天周六,下周一我要请小动物(小猫、小狗、小猪...)们吃饭,今明两天报名

 

饭“人”数,我好准备需要多少菜量

 

(注意以上重点:每个小动物都有‘吃’的方法(相同处),但吃的食物不一样(不同

 

处);去吃饭前,要先报名)

 

好,现在开始代码演示:

 父类:动物类

//父类:动物类Animal
   public  class Animal
    {
       protected string name = "";
       public Animal(string name)//构造函数
       {
           this.name = name;
        
       }

       public Animal()//构造函数
       {
           this.name = "";
       }
      
       //吃的虚方法
       public virtual string Eat()
       {
           return "";
       }
    }

 


子类:猫类 继承动物类

 //子类:猫类
    class Cat : Animal //继承动物类Animal
    {
        //调用父类Animal的构造函数
        public Cat()
            : base() 
        { }

        public Cat(string name)
            : base(name)
        { }

        //重写父类函数Eat()
        public override string Eat()
        {
            return "我是小猫,我叫" + name + "。 我吃鱼!";
        }
    }


子类:狗类 继承动物类

 //子类:狗类
    class Dog:Animal //狗类继承动物类Animal
    {
        //调用父类Animal的构造函数
        public Dog()
            : base()
        { }

        public Dog(string name)
            : base(name)
        { }

        //Eat()函数重写
        public override string Eat()
        {
            return "我是小狗,我叫" + name + "。 我吃骨头!";

        }
        
    }


子类:猪类 继承动物类

 //子类:猪类
    class Pig:Animal //猪类继承动物类Animal
    {
        //调用父类Animal的构造函数
        public Pig()
            : base()
        { }

        public Pig(string name)
            : base(name)
        { }

        //重写父类Animal的Eat()函数
        public override string Eat()
        {
            return "我是小猪,我叫" + name + "。 我吃馒头!";

        }
    }

 

组合实现:

 

客户端代码:

 

 private Animal[] arrayAnimal;//声明一个动物数组

        //点击“报名吃饭”按钮
        private void btnSignUp_Click(object sender, EventArgs e)
        {
            arrayAnimal = new Animal[4];//实例化最多可报名4个的动物数组对象
            
            //报名吃饭的对象:猫‘小丽’,狗‘小强’,猪‘小懒’,猫‘小红’
            arrayAnimal[0] = new Cat("小丽");
            arrayAnimal[1] = new Dog("小强");
            arrayAnimal[2] = new Pig("小懒");
            arrayAnimal[3] = new Cat("小红");

        }

        //点击“吃饭"按钮
        private void btnEat_Click(object sender, EventArgs e)
        {
            foreach (Animal item in arrayAnimal)//遍历数组,让所有报名吃饭的都Eat()
            {
                MessageBox.Show(item.Eat());  //各自调用各自的Eat()函数,来实现吃饭
            }
        }


分析一下客户端代码:我们定义了一个4个长度的数组,这就限制了只能有4个动物可以

 

报名去吃饭,多了就不允许了,少了也不行,很不合理,不灵活。

 

数组优点:数组在内存中连续存储,因此可以快速容易的从头到尾遍历元素,可以

 

快速修改元素等等。缺点:1)创建时必须要指定数组变量的大小;(2)在两个元

 

素之间添加元素很困难

 

鉴于数组的这两个缺点,我们用集合来实现:

 

客户端代码:

 

 using System.Collections;//增加集合命名空间

 IList arrayAnimal;//声明集合变量

        //点击“报名吃饭”按钮
        private void btnSignUp_Click(object sender, EventArgs e)
        {
            arrayAnimal = new ArrayList();//实例化ArrayList对象(注意:与数组不同之处是 没有指定arrayAnimal的大小)

            arrayAnimal.Add(new Cat("小丽"));
            arrayAnimal.Add(new Dog("小强"));
            arrayAnimal.Add(new Pig("小懒"));
            arrayAnimal.Add(new Cat("小红"));     
     
        }

        //点击“吃饭”按钮
        private void btnEat_Click(object sender, EventArgs e)
        {
            foreach (Animal item in arrayAnimal)//遍历ArrayList集合
            {
                MessageBox.Show(item.Eat());//各自实现各自的Eat()函数,来实现吃饭
            }
        }


再分析客户端代码:与数组相比,

 

集合优点: (1)不用事先设置大小,它可以根据使用大小按需增加,也就是说如果

 

明天 “狗小胖”和“猫小兰”也要报名去吃饭,那么可以直接增加arrayAnimal.Add

 

(new Dog("小胖"));arrayAnimal.Add(new Cat("小兰"));

 

(2)可以随意地添加、插入或移除元素,比数组方便灵活

 

比如:猫小丽下周一要去相亲,去不了啦。arrayAnimal.RemoveAt(0);

 

虽说集合的确有着数组没有的方便和灵活,但是,问题又来了——我邀请的是动物去吃

 

饭,如果在报名期间有其他种类(比方说“人”)也报名去吃饭:arrayAnimal.Add

 

(new Person("张三")); 不想接受他,他也来了,怎么办?

 

注意:Person类不继承Animal类,它是一个单独的类,这里没有写出来)

 

集合ArrayList的不足:ArrayList不管什么对象都是接受的,因为在它眼里所有

 

元素都欧式Object,这就使得如果你‘arrayAnimal.Add(new Person("张三"));’或者

 

‘arrayAnimal.Add(123);’‘arrayAnimal.Add("Good Morning");’在编译时都是没有问题

 

的,但在执行时,‘foreach(Animal item in arrayAnimal)’需要明确集中的元素的类型不

 

匹配错误,换句话说,ArrayList不是类型安全的。还有就是ArrayList对于存放值类型的

 

数据,比如int、string(string是一种拥有值类型特点的特殊引用类型)或者结构struct

 

的数据,用ArrayList就意味着都需要将值类型装箱为Object对象,使用集合元素时,还

 

需要执行拆箱操作,这就带来了很大的性能损耗。

 

 (关于数据类型哪些属于值类型,哪些属于引用类型,大家自己查资料学习!)

 

装箱:把值类型打包到Object引用类型的一个实例中。比如整型变量i被“装箱”并赋值

 

给对象obj:

 

int i=123;

 

Object obj=(object) i; //装箱

 

 

拆箱:从对象中提取值类型。上例中对象obj拆箱并将其赋值给整型变量i:

 

Obj=123;

 

i=(int)obj;  //拆箱

 

相对简单的赋值而言,装箱和拆箱过程需要进行大量的计算。对值类型进行装箱时,必

 

须分配并构造一个全新的对象。其次,拆箱所需的强制转换也需要进行大量的计算。总

 

之,装箱拆箱是耗费资源和时间的。而ArrayList集合在使用值类型数据时,其实就是不

 

断地做装箱和拆箱的工作,这显然很糟糕、很影响性能。

 

 

哎呀,数组收事先设置大小的控制,又不可随意添加、移除;集合吧又什么类型都接

 

受,并且不断装拆箱影响性能。该怎么办呢??哈哈泛型来喽。。。

 

泛型(概念):具有有占位符(类型参数)的类、结构、接口和方法,这些占位符是

 

类、结构、接口和方法所存储或使用的一个或多个类型的占位符,泛型集合类可以将类

 

型参数用作它所存储的对象的类型的占位符;类型参数作为其字段的类型和器方法的参

 

数类型出现。

 

概念很抽象。

 

其实关键就是:给集合加上类型,让该集合只能接受某一类型的对象

 

关键就是:在IList和List后面加‘<T>’,这个‘T’及时需要指定的集合的数据或对象类型

 

泛型实现:

 

客户端代码:

 
using System.Collections.Generic;//增加泛型集合命名空间


//声明一个泛型集合变量,用接口IList,注意:IList<Animal>表示此集合变量只能接受Animal类型,其他不可以。比较与声明集合变量IList arrayAnimal;的不同——是不是多了一个<Animal>,这个Animal就是这个集合能接受的对象类型
        IList<Animal> arrayAnimal;  

        //点击“报名吃饭”按钮
        private void btnSignUp_Click(object sender, EventArgs e)
        {
            arrayAnimal = new List<Animal>();//实例化List对象,此时也要指定List<T>的‘T’是Animal

            arrayAnimal.Add(new Cat("小丽"));
            arrayAnimal.Add(new Dog("小强"));
            arrayAnimal.Add(new Pig("小懒"));
            arrayAnimal.Add(new Cat("小红"));
            
        }

        //点击“吃饭”按钮
        private void btnEat_Click(object sender, EventArgs e)
        {
            foreach (Animal item in arrayAnimal)//遍历泛型集合
            {
                MessageBox.Show(item.Eat());//各自实现各自的Eat()函数,来实现吃饭
            }
        }


 

如果现在‘张三’再想报名arrayList.Add(new Person("张三"));会有什么后果?嘿嘿,

 

报错呗,因为泛型集合arrayAnimal不接受出Animal类型(或Animal子类型)以外的类型

 

对象。

 

泛型的优点:其实List和ArrayList在功能上是一样的,不同之处:泛型在声明和实

 

例化时都需要指定内部项的数据或对象类型,这就避免了集合的类型不安全问题和拆装

 

箱的性能问题了。

评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值