Наследование - Массивы родительского класса и массивы дочернего класса - приведение - PullRequest
0 голосов
/ 24 июня 2009

У меня проблемы с наследованием. Я могу делать то, что мне нужно, с отдельными экземплярами родительского класса и дочернего класса - как и ожидалось, методы родительского класса отлично работают с экземплярами дочернего класса.

Но я не вижу, как расширить класс, который использует массив родительского класса, таким образом, чтобы я мог хранить массив дочернего класса. Извините за размер кода, но я не думаю, что смогу прояснить проблему с помощью меньшего фрагмента.

Есть ли аккуратный выход из этой проблемы?

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 Ответ

2 голосов
/ 24 июня 2009

Вы должны использовать Generics для вашего 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);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...