继承 - 父类的数组和子类的数组 - 转换

时间:2009-06-24 08:19:34

标签: java generics inheritance

我在继承方面遇到了麻烦。我可以用父类和子类的单个实例做我需要的 - 正如预期的那样,父类的方法可以与子类的实例一起使用。

但是,我无法看到如何扩展使用父类数组的类,以允许我存储子类的数组。很抱歉代码的大小,但我认为我不能用较小的代码片段来解决问题。

这个问题有一个巧妙的方法吗?

public class TestIn {
    public static void main(String args[])  {
        CPUStats c = new CPUStats();
        c.set(4,5);     // OK
        c.dump();
        CPUStatsArray ca = new CPUStatsArray(24);
        ca.set(3, 21, 25);      // Data for hour 3 = 21 and 25
        ca.dump();              // Fails
    }
}

class GenericStats  {
    long s[];            // The stats, e.g. [0]=CPU% and [1]=Mem%
    // snip, more members

    // Constructor setting statistics to all zeros
    public GenericStats(int n)  {
        s = new long[n];
    }

    void set(long ... v)  {
        s = new long[v.length];
        for (int i = 0 ; i < v.length ; i++)  
            s[i] = v[i];
    }

    void dump()  {
        for (int i = 0 ; i < s.length ; i++)
            System.out.print("  [" + i + "] = " + s[i]);
        System.out.println();
    }
    // snip, a few useful methods
}

class CPUStats  extends GenericStats  {
    public CPUStats()  {
        super(2);
    }
    void dump() {
        System.out.println("CPU% = " + s[0] + ", and Mem% = " + s[1]);
    }
}

// class WhateverStats extends GenericStats  {
// ....
// }

// So far so good, I can use the useful methods of GenericStats on a CPUStats object

// Now I want an array of sets of statistics, e.g. for 24 sets of stats, one per hour 
class GenericStatsArray  {
   GenericStats gs[];
   int gslen;       // Length of s in each gs[]  (not the length of gs[])

    public GenericStatsArray(int numSets, int inlen)  {
        gs = new GenericStats[numSets];    // Problem caused by using the base class here
        gslen = inlen;
    }

    // Set values for element (e.g. hour) n
    void set(int n, long ... v)  {
        if (gs[n] == null)
            gs[n] = new GenericStats(gslen);
        gs[n].s = new long[v.length];
        for (int i = 0 ; i < v.length ; i++)  
            gs[n].s[i] = v[i];
    }

    void dump()  {
        System.out.println("GenericStatsArray");
        for (int i = 0 ; i < gs.length ; i++)  
            if (gs[i] != null)  {
                System.out.print("Array element [" + i + "]  ");
                gs[i].dump();
            }
        System.out.println("End GenericStatsArray\n");
    }
}

class CPUStatsArray extends GenericStatsArray  {
    public CPUStatsArray(int numSets)  {
        super(numSets, 2);
    }
 // Set values for element (e.g. hour) n
    void set(int n, long ... v)  {
        assert (v.length == 2);
        super.set(n, v);
    }
    void dump()  {
        System.out.println("CPUStatsArray");
        for (int i = 0 ; i < gs.length ; i++)  
            if (gs[i] != null)  {
                CPUStats c = (CPUStats) gs[i];      // This fails, 'GenericStats cannot be cast to CPUStats'
                System.out.print("Array element [" + i + "]  ");
                c.dump();
            }
        System.out.println("End CPUStatsArray\n");
    }
}

1 个答案:

答案 0 :(得分:2)

您应该为GenericsStatsArray使用泛型:

public class GenericStatsArray<T extends GenericStats> {
  GenericStats[] gs;
  int gslen;

  public GenericStatsArray(int numSets, int inlen)  {
    gs = new GenericStats[numSets];
    gslen = inlen;
  }

  //...
}

您可能需要在类中使用抽象工厂方法,因为您无法实例化通用元素(即您不能说new T())。

做这样的事情:

public abstract class GenericStatsArray<T extends GenericStats> {
 // ...
  protected abstract T NewT(int gslen);
  // ...
    gs[n] = NewT(gslen); // was: gs[n] = new GenericStats(gslen);
}

public class CPUStatsArray extends GenericStatsArray<CPUStats> {
  protected CPUStats NewT(int gslen){
    return new CPUStats(gslen);
  }
}