简体   繁体   中英

Generic field polymorphism in Java

I have really got confused with Generics please help me with my situation:

public <M extends AgeFactor> void setAgeFActor(M m){
    System.out.println("referene receiveed"+m.factor); //WHAT SHOULD IT REFER TO?? AgeFactor or type given at Runtime as young
    this.factor=m.factor;
}

In the above code the reference M m refers to AgeFactor or the type that i give at Runtime. Suppose i call it via:

ath1.setAgeFActor(new young()); //ath1 is referring to setAgeFActor method's class

and hierarchy being:

class AgeFactor {
    String factor;
}

class young extends AgeFactor {
    String factor = "Young";

    public String toString() {
        return " " + factor + " ";

    }
}

class experienced extends AgeFactor {
    String factor = "Experienced";

    public String toString() {
        return " " + factor + " ";

    }
}

class pro extends AgeFactor {
    String factor = "Pro";

    public String toString() {
        return " " + factor + " ";

    }
}

What i want to know is why m.factor refer to AgeFactor 's field factor ?? m.factor should referring to young or pro the type i give at Runtime.

If m is actually referring to AgeFactor then i understand that m.factor will refer to AgeFactor's factor always because polymorphism is not applied to fields. If so, then what is the need of generics? Are Java's generics generic itself? Pleas help me getting over Generics.

Fields aren't overridden in the way that methods are. If you want this kind of polymorphism, you have to do it with methods, not with fields.

Here, experienced and pro have two different fields named factor , one from AgeFactor , and one from experienced and pro . The fact that it has the same name is completely coincidental: if you have an object, and all that's known about it is that it's an AgeFactor , then the AgeFactor version of that field will be used.

A more sensible version of this design might be to have only one field named factor , and to set it in the constructors of each class.

AgeFactor is a class not an interface . Thus it (AgeFactor) has its own instance variables. Sub-classes (such as young) have their own instance variables. A sub-classe's instance variables are entirely separate from any sub/super instance variables. As mentioned above only non-static methods participate in polymorphism (ie, sub-classes can override methods of a super class). One way to do what you want is to make AgeFactor an interface with a 'getFactor' method. Each of the sub classes would implement a getFactor() method which returns the desired constant.

Note that in java unlike c++ class casts DO NOT change object reference values - so method references are preserved across casts. try the following:

class Ages
{
  public static void main(String args[])
  {
    young yy = new young();
    System.out.println(yy.toString());
    System.out.println(yy.factor);
    System.out.println(((AgeFactor) yy).toString());
    System.out.println(((AgeFactor) yy).factor);
    System.out.println(cc(yy));
  }

  static <AA extends AgeFactor> String cc(AA af)
  {
    return af.factor;
  }

  static class AgeFactor {
      String factor = "unknown";
      public String toString() {
          return " " + factor + " ";

      }
  }

  static class young extends AgeFactor {
      String factor = "Young";

      public String toString() {
          return " " + factor + " ";

      }
  }

  static class experienced extends AgeFactor {
      String factor = "Experienced";

      public String toString() {
          return " " + factor + " ";

      }
  }

  static class pro extends AgeFactor {
      String factor = "Pro";

      public String toString() {
          return " " + factor + " ";

      }
  }
}

Note also, in Java, generics are entirely compile-time constructs. Via a process known as erasure, the code is compiled without any reference to the 'generic'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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