简体   繁体   English

没有泛型的代码重用

[英]Code reuse without generics

Say that I need to create 3 linked lists one for int, one for Strings and one for a different type of custom object. 假设我需要创建3个链接列表,一个用于int,一个用于Strings,一个用于其他类型的自定义对象。 If I was using generics it would be easy to do this just by creating one linked list but is there a way to avoid writing the same repetetive code 3 times if I was not using generics? 如果我使用的是泛型,只需创建一个链接列表即可轻松实现,但是如果我不使用泛型,是否可以避免3次编写相同的重复代码?

If you use Integer instead of int , then yes. 如果您使用Integer而不是int ,那么可以。 In this case, all three objects are subclasses of Object so your Linked List class could just deal with Object s. 在这种情况下,所有三个对象都是Object子类,因此您的Linked List类只能处理Object

The code would look, roughly, like: 该代码大致如下所示:

class MyLinkedList{
    public void add(Object){...}
    public Object remove(Object){...}
    ...
}

Before the introduction of generics in Java 1.5 the Collections all used the type Object, so you would have a linked list of Objects. 在Java 1.5中引入泛型之前,Collections都使用Object类型,因此您将拥有一个Objects链表。 You then had to make sure yourself that you were adding, retrieving and casting the right types. 然后,您必须确保自己要添加,检索和转换正确的类型。

I don't see any reason why you shouldn't or wouldn't use generics since using Java 1.4 is hardly necessary or recommended anymore. 我看不到为什么不应该或不应该使用泛型的任何原因,因为不再需要或不建议使用Java 1.4。

您不能对ints vs Strings使用相同的代码,但是假设您的意思是Integers,则必须创建一个存储java.lang.Objects的LinkedList,顺便说一句,这是基于通用的LinkedLists所做的。

You can abstract out the type that the linked list handles into your own type, say StringOrIntOrCustom , that has one of each type, and a flag that specifies which one is the valid one to use. 您可以将链表处理的类型抽象为您自己的类型,例如StringOrIntOrCustom ,该类型具有每种类型之一,并带有一个标志,该标志指定要使用的有效类型。 However, you'd need to do a lot of checking to make sure you're not doing an operation that a type does not support whenever you use this data type. 但是,您需要进行大量检查,以确保您没有在每次使用此数据类型时都执行该类型不支持的操作。

You could do it with out generics, but you would have no compile time type safety checking and you will have to add all the type casting manually. 您可以在没有泛型的情况下完成此操作,但是您将无需进行编译时类型安全检查,而必须手动添加所有类型转换。

But then again you will essentially doing what the compiler does when you use generics. 但是话又说回来,您将基本上执行使用泛型时编译器的工作。 Now it's just error prone and manual. 现在,它只是容易出错和手动的。

Yes, you can do this, and it's not that hard. 是的,您可以做到,而且并不难。

abstract class ListNode {
   public ListNode next_;
};

interface ListNodeFactory {
   public ListNode createListNode();
}

You then create a List class the manipulates ListNode objects. 然后,您创建一个操作ListNode对象的List类。 It will have a function it calls to create a new ListNode when it needs one. 当需要一个新的ListNode时,它将调用一个函数来创建一个新的ListNode。 The add method would take a ListNodeFactory argument. add方法将使用ListNodeFactory参数。 I would suggest most of the methods be protected because no client that's not a derived class is likely to use it. 我建议大多数方法都应protected因为不是派生类的任何客户端都不可能使用它。

The you create a derived class from List for each type. 您将为每种类型从List创建一个派生类。 You will have to wrap each method with one that takes the type you want. 您将必须使用一种采用所需类型的方法来包装每个方法。 You will also have to create a ListNodeFactory implementation that creates new list nodes with the appropriate type in them. 您还必须创建一个ListNodeFactory实现,该实现将创建具有适当类型的新列表节点。 It will also have to cast the ListNode objects it gets out from traversals or removals to the appropriate types in order to get at the data. 为了获取数据,它还必须将从遍历或删除中获取的ListNode对象转换为适当的类型。 Here is an example: 这是一个例子:

class IntListNode extends ListNode {
   public int data_;
   public IntListNode(int x) {
      data_ = x;
   }
}

class IntListNodeFactory implements ListNodeFactory {
   IntListNodeFactory() {
       nextdataset_ = false;
   }
   IntListNodeFactory(int x) {
       nextdataset_ = true;
       data_ = x;
   }
   void setNextData(int x) {
       nextdataset_ = true;
       nextdata_ = x;
   }
   public ListNode createListNode() {
       if (!nextdataset_) {
          throw Exception("Tried to create a node with no data!");
       } else {
          ListNode result = new IntListNode(data_);
          nextdataset_ = false;
          return result;
       }
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM