我如何获得内部类继承封闭类的泛型类型? [英] How do I get an inner class to inherit enclosing class' generic type?

查看:102
本文介绍了我如何获得内部类继承封闭类的泛型类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java 6.



我无法让内部类使用相同的泛型类作为它的封闭类。目前我有

  public class TernarySearchTree< / p> T> {
...
受保护的类TSTNode< T> {
//访问亲属数组的索引值
protected static final int PARENT = 0,LOKID = 1,EQKID = 2,HIKID = 3;
受保护的char splitchar;
保护TSTNode< T> [] 亲戚们;
私人T数据;

protected TSTNode(char splitchar,TSTNode< T> parent){
this.splitchar = splitchar;
relatives = new TSTNode [4];
亲属[父母] =父母;
}
}
}

现在我收到警告


类型参数T隐藏类型T


如果我从内部类中移除了类型参数(即从受保护的类TSTNode< T>< T>中移除< T> / code> line),然后我得到一行 relatives = new TSTNode [4] 的编译错误。



我怎样才能把事情做好?

解决方案




  • < T> 类型参数从 TSTNode (即使它不是通用的) - 它仍然可以访问外部的< T> 重命名类 TSTNode 中的< T>

    > [更新]



    以下是四种重写代码的方法。他们都编译。我认为你应该考虑使用 EnumMap (见下面的版本4)。

    版本1 :在内部类中使用一个不同名称的类型参数。您需要使用List而不是数组。

      public class TernarySearchTree< T> {

    受保护的类TSTNode< U> {
    //访问亲属数组的索引值:
    protected static final int PARENT = 0,LOKID = 1,EQKID = 2,HIKID = 3;

    保护字符splitchar;
    protected List< TSTNode< U>>亲戚们;
    私人U数据;

    protected TSTNode(char splitchar,TSTNode< U> parent){
    this.splitchar = splitchar;
    relatives = new ArrayList< TSTNode< U>>();
    for(int i = 0; i< HIKID; ++ i){//分配亲戚中的4个位置
    relatives.add(null);
    }
    relatives.set(PARENT,parent);
    }
    }

    private TSTNode< T>节点; //当你使用它时,将T作为U

    public TernarySearchTree(){
    node = new TSTNode< T>(',',null); //当你使用它时,将T作为U
    }
    }



    第2版:从封装类继承T

      public class TernarySearchTree< T> {

    protected class TSTNode {
    //访问亲属数组的索引值:
    protected static final int PARENT = 0,LOKID = 1,EQKID = 2,HIKID = 3;

    保护字符splitchar;
    protected List< TSTNode>亲戚们;
    私人T数据;

    protected TSTNode(char splitchar,TSTNode parent){
    this.splitchar = splitchar;
    relatives = new ArrayList< TSTNode>();
    for(int i = 0; i< HIKID; ++ i){//分配亲戚中的4个位置
    relatives.add(null);
    }
    relatives.set(PARENT,parent);
    }
    }

    私人TSTNode节点;

    public TernarySearchTree(){
    node = new TSTNode(',',null);


    第3版:use一个Map(而不是一个List)

      public class TernarySearchTree< T> {

    protected class TSTNode {
    //访问亲属数组的索引值:
    protected static final int PARENT = 0,LOKID = 1,EQKID = 2,HIKID = 3;

    保护字符splitchar;
    protected Map< Integer,TSTNode>亲戚们;
    私人T数据;

    protected TSTNode(char splitchar,TSTNode parent){
    this.splitchar = splitchar;
    //创建一个哈希映射。无需预先分配!
    relatives = new HashMap< Integer,TSTNode>();
    relatives.put(父母,父母); // set - >放置
    }
    }

    私人TSTNode节点;

    public TernarySearchTree(){
    node = new TSTNode(',',null);
    }
    }
    }

    第4版:将索引定义为enum +使用EnunMap(而不是哈希映射)

    pre $ public class TernarySearchTree< T> ; {

    保护静态枚举索引{
    PARENT,LOKID,EQKID,HIKID;
    }

    保护类TSTNode {
    保护字char splitchar;
    protected EnumMap< Index,TSTNode>亲戚们;
    私人T数据;

    protected TSTNode(char splitchar,TSTNode parent){
    this.splitchar = splitchar;
    //创建一个EnumMap。
    relatives = new EnumMap< Index,TSTNode>(Index.class);
    relatives.put(Index.PARENT,parent);
    }
    }

    私人TSTNode节点;

    public TernarySearchTree(){
    node = new TSTNode(',',null);
    }
    }

    [更新2]
    请记住一件事:使用EnumMap而不是顺序索引


    I'm using Java 6.

    I'm having trouble getting my inner class to use the same generic class as its enclosing class. Currently I have

    public class TernarySearchTree < T > {
        ...
        protected class TSTNode < T > {
            // index values for accessing relatives array
            protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3; 
            protected char splitchar;
            protected TSTNode < T > [] relatives;
            private T data;
    
            protected TSTNode(char splitchar, TSTNode < T > parent) {
                this.splitchar = splitchar;
                relatives = new TSTNode[4];
                relatives[PARENT] = parent;
            }
        }
    }
    

    Right now I get the warning

    The type parameter T is hiding the type T

    If I remove the type parameter from the inner class (i.e. remove the <T> from teh protected class TSTNode<T> line), then I get a compile error on the line relatives = new TSTNode[4].

    How can I make everything right?

    解决方案

    You can either:

    • remove the <T> type parameter from TSTNode (i.e., make it non-generic) - it will still have access to the outer <T>.

    • rename the <T> type parameter in class TSTNode to (say) U.

    [UPDATE]

    Below are four different ways to rewrite your code. All of them compile. I think you should consider the use of an EnumMap (see Version 4, below).

    Version 1: use a differenly named type parameter in the inner class. you need to use a List instead of an array.

      public class TernarySearchTree<T> {
    
        protected class TSTNode<U> {
          // index values for accessing relatives array:
          protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3;
    
          protected char splitchar;
          protected List<TSTNode<U>> relatives;
          private U data;
    
          protected TSTNode(char splitchar, TSTNode<U> parent) {
            this.splitchar = splitchar;
            relatives = new ArrayList<TSTNode<U>>();
            for (int i = 0; i < HIKID; ++i) {  // Allocate 4 slots in relatives
              relatives.add(null);
            }
            relatives.set(PARENT, parent);
          }          
        }
    
        private TSTNode<T> node; // When you use it, pass T as U
    
        public TernarySearchTree() {
          node = new TSTNode<T>(',', null);  // When you use it, pass T as U 
        }
      }
    

    Version 2: inherit T from enclosing class

      public class TernarySearchTree<T> {
    
        protected class TSTNode {
          // index values for accessing relatives array:
          protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3;
    
          protected char splitchar;
          protected List<TSTNode> relatives;
          private T data;
    
          protected TSTNode(char splitchar, TSTNode parent) {
            this.splitchar = splitchar;
            relatives = new ArrayList<TSTNode>();
            for (int i = 0; i < HIKID; ++i) {  // Allocate 4 slots in relatives
              relatives.add(null);
            }
            relatives.set(PARENT, parent);
          }
        }
    
        private TSTNode node; 
    
        public TernarySearchTree() {
          node = new TSTNode(',', null);  
        }
      }
    

    Version 3: use a Map (instead of a List)

      public class TernarySearchTree<T> {
    
        protected class TSTNode {
          // index values for accessing relatives array:
          protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3;
    
          protected char splitchar;
          protected Map<Integer, TSTNode> relatives;
          private T data;
    
          protected TSTNode(char splitchar, TSTNode parent) {
            this.splitchar = splitchar;
            // Create a hash map. No need to pre-allocate!
            relatives = new HashMap<Integer, TSTNode>(); 
            relatives.put(PARENT, parent); // set -> put
          }
        }
    
        private TSTNode node; 
    
        public TernarySearchTree() {
          node = new TSTNode(',', null);  
        }
      }
    }
    

    Version 4: define the indices as an enum + use an EnunMap (instead of a hash map)

      public class TernarySearchTree<T> {
    
        protected static enum Index {
          PARENT, LOKID, EQKID, HIKID;
        }
    
        protected class TSTNode {    
          protected char splitchar;
          protected EnumMap<Index, TSTNode> relatives;
          private T data;
    
          protected TSTNode(char splitchar, TSTNode parent) {
            this.splitchar = splitchar;
            // Create an EnumMap. 
            relatives = new EnumMap<Index, TSTNode>(Index.class);
            relatives.put(Index.PARENT, parent); 
          }
        }
    
        private TSTNode node; 
    
        public TernarySearchTree() {
          node = new TSTNode(',', null);  
        }
      }
    

    [Update 2] One thing to keep in mind: Use EnumMap instead of ordinal indexing

    这篇关于我如何获得内部类继承封闭类的泛型类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆