Java Tutorial/Generics/Bounded Types

Материал из Java эксперт
Перейти к: навигация, поиск

Bounded Types

The type argument for T must be either Number, or a class derived from Number.



class Stats<T extends Number> { 
  T[] nums;
   
  Stats(T[] o) { 
    nums = o; 
  } 
 
  double average() { 
    double sum = 0.0;
    for(int i=0; i < nums.length; i++) 
      sum += nums[i].doubleValue();
    return sum / nums.length;
  } 
} 
 
public class MainClass { 
  public static void main(String args[]) { 
    Integer inums[] = { 1, 2, 3, 4, 5 };
    Stats<Integer> iob = new Stats<Integer>(inums);
    double v = iob.average();
    System.out.println("iob average is " + v);
    Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
    Stats<Double> dob = new Stats<Double>(dnums);
    double w = dob.average();
    System.out.println("dob average is " + w);
  } 
}



iob average is 3.0
dob average is 3.3


Bounded Wildcards

class Two {
  int x, y;
  Two(int a, int b) {
    x = a;
    y = b;
  }
}
class Three extends Two {
  int z;
  Three(int a, int b, int c) {
    super(a, b);
    z = c;
  }
}
class Four extends Three {
  int t;
  Four(int a, int b, int c, int d) {
    super(a, b, c);
    t = d;
  }
}
class Gen<T extends Two> {
  T[] coords;
  Gen(T[] o) {
    coords = o;
  }
}
// Demonstrate a bounded wildcard.
public class MainClass {
  static void showTwo(Gen<?> c) {
    System.out.println("X Y Coordinates:");
    for (int i = 0; i < c.coords.length; i++)
      System.out.println(c.coords[i].x + " " + c.coords[i].y);
    System.out.println();
  }
  static void showThree(Gen<? extends Three> c) {
    System.out.println("X Y Z Coordinates:");
    for (int i = 0; i < c.coords.length; i++)
      System.out.println(c.coords[i].x + " " + c.coords[i].y + " " + c.coords[i].z);
    System.out.println();
  }
  static void showAll(Gen<? extends Four> c) {
    System.out.println("X Y Z T Coordinates:");
    for (int i = 0; i < c.coords.length; i++)
      System.out.println(c.coords[i].x + " " + c.coords[i].y + " " + c.coords[i].z + " "
          + c.coords[i].t);
    System.out.println();
  }
  public static void main(String args[]) {
    Two td[] = { new Two(0, 0), new Two(7, 9), new Two(18, 4), new Two(-1, -23) };
    Gen<Two> tdlocs = new Gen<Two>(td);
    System.out.println("Contents of tdlocs.");
    showTwo(tdlocs); // OK, is a TwoD
    Four fd[] = { new Four(1, 2, 3, 4), new Four(6, 8, 14, 8), new Four(22, 9, 4, 9),
        new Four(3, -2, -23, 17) };
    Gen<Four> fdlocs = new Gen<Four>(fd);
    System.out.println("Contents of fdlocs.");
    // These are all OK.
    showTwo(fdlocs);
    showThree(fdlocs);
    showAll(fdlocs);
  }
}



Contents of tdlocs.
X Y Coordinates:
0 0
7 9
18 4
-1 -23
Contents of fdlocs.
X Y Coordinates:
1 2
6 8
22 9
3 -2
X Y Z Coordinates:
1 2 3
6 8 14
22 9 4
3 -2 -23
X Y Z T Coordinates:
1 2 3 4
6 8 14 8
22 9 4 9
3 -2 -23 17


Upper/lower bound for a wildcard

Establishing an upper bound for a wildcard



<? extends superclass>





Using Wildcard Arguments

// Use a wildcard.
class GenericStats<T extends Number> {
  T[] nums;
    
  GenericStats(T[] o) {
    nums = o;
  }
  double average() {
    double sum = 0.0;
     for(int i=0; i < nums.length; i++){
      sum += nums[i].doubleValue();
     }
    return sum / nums.length;
  }
  boolean sameAvg(GenericStats<?> ob) {
    if(average() == ob.average()) 
      return true;
    return false;
  }
}  
  
public class MainClass {
  public static void main(String args[]) {
    Integer inums[] = { 1, 2, 3, 4, 5 }; 
    GenericStats<Integer> iob = new GenericStats<Integer>(inums);
    double v = iob.average();
    System.out.println("iob average is " + v);
 
    Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
    GenericStats<Double> dob = new GenericStats<Double>(dnums);
    double w = dob.average();
    System.out.println("dob average is " + w); 
 
    Float fnums[] = { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F }; 
    GenericStats<Float> fob = new GenericStats<Float>(fnums);
    double x = fob.average(); 
    System.out.println("fob average is " + x);
 
    System.out.print("Averages of iob and dob ");
    if(iob.sameAvg(dob)){
      System.out.println("are the same."); 
    }else{
      System.out.println("differ."); 
    }
    
    System.out.print("Averages of iob and fob ");
    if(iob.sameAvg(fob)){
      System.out.println("are the same."); 
    }else{
      System.out.println("differ.");
    }
  }
}



iob average is 3.0
dob average is 3.3
fob average is 3.0
Averages of iob and dob differ.
Averages of iob and fob are the same.