泛型及其继承

  泛型,面向对象编程的一种编程方式,可以很好地进行代码重用(尤其是‘算法重用’),极大地提高了开发效率。换言之,泛型可以派生出一个类,让它继承基类的所有能力。派生类只需要重写虚方法,或添加一些新方法,就可以定制派生类的行为。

  算法重用,简单地说,开发人员先定义一个算法,比如排序,搜索等,但定义算法的开发人员并不设定该算法要操作什么数据类型,该算法可广泛地应用于不同类型的对象。然后另一个开发人员只要指定了算法要操作的具体操作类型,就可以开始使用这个现成的算法了。

  泛型类型也是类型,所以能从其他类型派生。使用一个泛型类型,并指定类型实参时,实际是在CLR中定义一个新的类型对象,新的类型对象是从泛型类型派生自的那个类型派生的。换言之,List<T>是从Object派生的,所以List<String>也是从Object派生的。

看两段代码

示例1:

internal sealed class NodeDemo<T>
{
    public T m_data;
    public NodeDemo<T> m_next;

    public NodeDemo(T data, NodeDemo<T> next)
    {
        m_data = data;
        m_next = next;
    }

    public NodeDemo(T data) : this(data, null) { }

    public override string ToString()
    {
        return m_data.ToString() + ((m_next != null) ? m_next.ToString() : null);
    }
}

// 调用代码
static void Main(string[] args)
{  // 节点类型都是 Char
    NodeDemo<Char> head = new NodeDemo<Char>(‘C‘);
    head = new NodeDemo<Char>(‘B‘, head);
    head = new NodeDemo<Char>(‘A‘, head);

    Console.WriteLine(head.ToString());
    Console.ReadKey();
}

// 代码执行 显示‘ABC’

  示例1中,对于m_next字段引用的另一个节点来说,它的m_data字段必须包含相同的数据类型。这意味着在链表包含的节点中,所有数据项都必须具有相同的数据类型。当然,若到处都用Node<Object>,那么确实可以做到,但会丧失编译时的类型安全性,而且值类型会被装箱。

  所以一个更好的办法是定义一个非泛型Node基类,再定义一个TypedNode类(Node类作为基类)。这样一来,就可以创建一个链表,其中每个节点都可以是一种具体的数据类型(不能是Object),同时获得编译时的类型安全性,并防止值类型装箱。具体实现参考示例2。

示例2:

internal class Node
{
    protected Node m_next;
    public Node(Node next)
    {
        m_next = next;
    }
}

internal sealed class TypedNode<T> : Node
{
    public T m_data;

    public TypedNode(T data, Node next) : base(next)
    {
        m_data = data;
    }

    public TypedNode(T data) : this(data, null) { }

    public override string ToString()
    {
        return m_data.ToString() + ((m_next != null) ? m_next.ToString() : null);
    }
}

// 调用代码
static void Main(string[] args)
{  // 节点类型都不一样
    Node head = new TypedNode<Char>(‘.‘);
    head = new TypedNode<DateTime>(DateTime.Now, head);
    head = new TypedNode<String>("Today is ", head);

    Console.WriteLine(head.ToString());
    Console.ReadKey();
}

// 代码执行 显示‘Today is 2015-6-18 10:00:00.’
时间: 2024-11-03 11:03:42

泛型及其继承的相关文章

java基础之泛型的继承

关于泛型的基本介绍和理解请参考以下几篇文章,或查询更多资料: 泛?型?与?泛?型?继?承 泛型(包括泛型抽象类的继承) 泛型的继承测试 本篇以简单的List<>方式来进行说明. ArrayList<Object>继承了List<Object>, ArrayList<String>没有继承List<Object> List<?>等价于List<? extends Object> 请参考以下代码: /** * author D

泛型深入--java泛型的继承和实现、泛型擦除

泛型实现类: package generic; /** * 泛型父类:子类为“富二代”:子类的泛型要比父类多 * 1,保留父类的泛型-->子类为泛型类 * 2,不保留父类泛型-->子类按需实现 * * * 子类[重写方法]的参数类型 -->随父类而定 * 子类新增的方法,参数类型随子类而定 * 子类中使用父类的[属性] -->随父类而定 * 子类使用自己的属性-->随子类而定 * @author Administrator * */ public abstract class

Java泛型学习笔记 - (六)泛型的继承

在学习继承的时候, 我们已经知道可以将一个子类的对象赋值给其父类的对象, 也就是父类引用指向子类对象, 如: 1 Object obj = new Integer(10); 这其实就是面向对象编程中的is-a关系. 既然上面的代码正确, 那么在泛型中, 也可以使用如下代码: 1 public class Box<T> { 2 private T obj; 3 4 public Box() {} 5 6 public T getObj() { 7 return obj; 8 } 9 10 pub

java泛型 generics --- 第三部分 泛型、继承、和子类型

Generics, Inheritance, and Subtypes 正如你所知,可以把一种对象类型赋值给另一种类型,只要他们是兼容的.例如,你可以把Integer对象赋值给Object. Object someObject = new Object(); Integer someInteger = new Integer(10); someObject = someInteger; // OK 在面向对象技术中,这被称作"is a"关系.即一个Integer是一中Object,该赋

类泛型--必须继承接口

where 用法

Java泛型:泛型的定义(类、接口、对象)、使用、继承

地址   http://blog.csdn.net/lirx_tech/article/details/51570138 1. 设计泛型的初衷: 1) 主要是为了解决Java容器无法记忆元素类型的问题: i. 由于Java设计之初并不知道会往容器中存放什么类型的元素,因此元素类型都设定为Object,这样就什么东西都能放了! ii. 但是这样设计有明显的缺点: a. 取出元素的时候必须进行强制类型转换(尽管集合在运行时里面元素的"运行时类型"不变,即元素的getClass返回的还是最初

MassTransit 学习记录(杂项) IConsumer泛型实现和多继承

前面讲到过,MassTransit的消费三种方式,Consumer方式就是其中的一种,IConsumer<T>是该方式的约定接口. 一般来说,每个Exchange对应一个Consumer,即常规代码如下 public class SomeConsumer : IConsumer<ClassA> { public Task Consume(ConsumeContext<ClassA> context) { throw new NotImplementedException

Java的泛型和通配符

泛型:1.泛型类    class A<T>{    }2.在创建实例时,需要为其类型变量赋值 3.泛型方法    class A<T>{        public T fun1(){}        public void fun2(T t){}        //以上两个都不是泛型方法,他们是泛型类里面的一个方法        //发现方法要求需要在方法上有泛型的定义        public <T> T fun3(){}//此为泛型方法    } class

十一、C# 泛型

为了促进代码重用,尤其是算法的重用,C#支持一个名为泛型的特性. 泛型与模块类相似. 泛型使算法和模式只需要实现一交.而不必为每个类型都实现一次.在实例化的时候,传入相应的数据类型便可. 注:可空值类型  也是基于泛型实现的. 泛型的本质 就是给某些复杂的类型,抽象一套数据类型的别名.然后可以在这复杂类型当中使用这些别名. 当运行时,可以通过为这一套抽象的数据类型指定实际的数据类型. 1.概述 利用泛型,可以在声明变量时创建用来处理特定类型的特殊数据结构.程序员定义这种参数化类型, 使特定泛型类