泛型(Generic)类的使用原因和使用方式

我们每个苹果都套个盒子,给每本书都套个盒子,但是苹果盒子和书盒子是不同的,
这样下去如果有更多的东西需要套盒子,1000种产品有1000种相应的盒子,造成类型极度膨胀非常难以维护。

    class Program
    {
        static void Main(string[] args)
        {
            Apple apple = new Apple() { Color = "Red" };
            AppleBox abox = new AppleBox() { Cargo = apple };
            Console.WriteLine(abox.Cargo.Color);

            Book book = new Book() {Name = "New Book"};
            BookBox bbox = new BookBox() { Cargo = book };
            Console.WriteLine(bbox.Cargo.Name);
        }
    }
    class Apple
    {
        public string Color { get; set; }
    }
    class Book
    {
        public string Name { get; set; }
    }
    class AppleBox
    {
        public Apple Cargo { get; set; }
    }

    class BookBox
    {
        public Book Cargo { get; set; }
    }

我们只准备一种盒子,让这种盒子有不同属性可以装任何东西。
如果有1000种东西需要1000种盒子,在Box类种有1000个对应属性,每次只有1个有用,999个没有用。
另外如果又来了新的物品,则要修改Box类,增加新的属性。忘记增删属性会导致bug和代码不完善,这叫做成员膨胀。

    class Program
    {
        static void Main(string[] args)
        {
            Apple apple = new Apple() { Color = "Red" };
            Book book = new Book() { Name = "New Book" };
            Box box1 = new Box() { Apple = apple };//用了Apple属性,没用Book属性
            Box box2 = new Box() { Book = book };//反之
        }
    }
    class Apple
    {
        public string Color { get; set; }
    }
    class Book
    {
        public string Name { get; set; }
    }
    class Box
    {
        public Apple Apple { get; set; }
        public Book Book { get; set; }
    }

还有一种解决方案,那就是在声明Box的属性的时候 不要指明具体类型,用Object类型就可以了。

   class Program
   {
       static void Main(string[] args)
       {
           Apple apple = new Apple() { Color = "Red" };
           Book book = new Book() { Name = "New Book" };
           Box box1 = new Box() { Cargo = apple };
           Box box2 = new Box() { Cargo = book };
       }

}

Apple和Box类略

    class Box
    {
        public  object Cargo { get; set; }
    }

但是我们看不到Color属性了

如果想只当盒子里是Apple的时候才看到Color属性,那么就强制类型转换(略)或者使用as操作符

            Console.WriteLine((box1.Cargo as Apple)?.Color);

其中,box1里是苹果,box2里是书,这里(box1.Cargo as Apple)表示对象,“?”表示如果是Apple则.Color,否则不执行。

但是依然很麻烦呀。

因此我们引入泛型!

    class Box<类型参数>
    {
        public  类型参数 Cargo { get; set; }
    }

所谓类型参数就是一个标识符,是一个泛化的类型
因此我们给类型参数起名TCargo,T表示泛型
因此修改Box类为:

    class Box<TCargo>
    {
        public  TCargo Cargo { get; set; }
    }

Program类变为

    class Program
    {
        static void Main(string[] args)
        {
            Apple apple = new Apple() { Color = "Red" };
            Book book = new Book() { Name = "New Book" };
            Box<Apple> box1 = new Box<Apple>() { Cargo = apple };
            Box<Book> box2 = new Box<Book>() { Cargo = book };
            Console.WriteLine(box1.Cargo.Color);
            Console.WriteLine(box2.Cargo.Name);
        }
    }

我们发现这样是可以根据装不同东西的盒子,点出不同的属性的,完美解决了问题。

原文地址:https://www.cnblogs.com/maomaodesu/p/11649916.html

时间: 2024-08-02 22:42:15

泛型(Generic)类的使用原因和使用方式的相关文章

Java基础之Comparable接口, Collections类,Iterator接口,泛型(Generic)

一.Comparable接口, Collections类 List的常用算法: sort(List); 排序,如果需要对自定义的类进行排序, 那就必须要让其实现Comparable接口, 实现比较两个类大小的方法 shuffle(List); 随机排列 void reverse(List); 逆序排列(Linked效率较高) copy(); 复制集合, 前提是size()相同(长度, 和容量的区别) fill(List, Object);使用某个对象填充整个List binarySearch()

java 泛型(Generic)

java泛型(generic) 2016-07-11 问题 向集合存储元素存在安全性问题,即很可能不知道已有的集合中已经存储的元素的类型是什么,这时就不应该向该集合随便添加元素,否则与集合的设计的初衷相悖,因为集合存储的是同类型的元素,而且以后取集合中的元素不知道该转为什么类型. 从集合中获取元素需要强制类型转换,可能出现ClassCastException问题 未使用泛型举例: 说明:任何Object子类均可以存入Object集合,但是从集合中获取元素,则是Object对象,需要强制转换,可能

C#泛型(Generic)

一.什么是泛型 泛型(Generic)是C#语言2.0.通用语言运行时(CLR)2.0..NET Framework2.0推出来的新特性. 泛型为.NET框架引入类型参数(Type Parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个参具体数. 具体的参数类型可延迟到声明和使用时再确定.避免了运行时类型转换或装箱操作的代价和风险. 二.泛型的使用和对比 2.1.CommandMethod(普通方法) 1 /// <summary> 2 /// 打印一个Int值 3 //

JAVA学习笔记(五十六)- 泛型 Generic Types

泛型 Generic Types import java.util.ArrayList; import java.util.List; /* * 泛型 Generic Types * 集合泛型 * 类泛型 * 方法泛型 */ public class Test01 { public static void main(String[] args) { // 1.集合泛型,保证集合中元素的类型安全 List<Integer> nums = new ArrayList<Integer>(

Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口

Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器内的元素的遍历 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为"轻量级"对象,因为创建它的代价小. Java中的Iterator功能比较简单,并且只能单向移动: (1) 使用方法iterator()要求容器返回一个I

泛型(Generic)

1.定义:一种特殊的变量,保存的是引用变量的类型 2.好处:避免数据类型的转换;将运行时期ClassCastException提前到编译时期 3.自定义带泛型的类:     public class A<泛型名>{ }     注:类中凡是使用到数据类型的地方,都可以使用泛型名代替;         泛型名自定义,但是将来使用者只能传递引用数据类型; 1 代码实现: 2 //自定义泛型类和泛型方法: 3 class A<MM>{ 4 private MM name; 5 priva

爪哇国新游记之十八----泛型栈类

import java.lang.reflect.Array; /** * 泛型栈 * * @param <T> */ public class Stack<T>{ private Class<T> type;// 栈元素所属的类 private int size;// 栈深度 private T[] arr;// 用数组存储 private int top;// 栈顶元素的下标 public Stack(Class<T> type,int size){ t

开发积累—泛型工具类

前言:使用SSH2中使用的泛型工具类,以前写泛型比较麻烦.今天收集到一个工具类,好东呀!!分享给大家,绝对有用.JAVA版的web应用程序使用. 示例代码: import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** *Hibernate工具类,用于获取S

C++ Primer 学习笔记_83_模板与泛型编程 --一个泛型句柄类

模板与泛型编程 --一个泛型句柄类 引言: [小心地雷] 这个例子体现了C++相当复杂的语言应用,理解它需要很好地理解继承和模板.在熟悉了这些特性之后再研究这个例子也许会帮助.另一方面,这个例子还能很好地测试你对这些特性的理解程度. 前面示例的Sales_item和Query两个类的使用计数的实现是相同的.这类问题非常适合于泛型编程:可以定义类模板管理指针和进行使用计数.原本不相关的Sales_item类型和 Query类型,可通过使用该模板进行公共的使用计数工作而得以简化.至于是公开还是隐藏下