简体   繁体   English

Java中的通用字段多态性

[英]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. 在上面的代码中,引用M m表示AgeFactor或我在运行时给出的类型。 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引用AgeFactor的场factor m.factor should referring to young or pro the type i give at Runtime. m.factor应该指的是我在运行时给出的youngpro类型。

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. 如果m实际上是指AgeFactor,那么我理解m.factor总是指AgeFactor的因数,因为多态性未应用于字段。 If so, then what is the need of generics? 如果是这样,那么泛型有什么需要? Are Java's generics generic itself? Java的泛型本身是泛型的吗? 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 . 在这里, experiencedpro有一个名为两个不同领域的factor ,一个来自AgeFactor ,以及一个从experiencedpro 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. 它具有相同的名称的事实完全是偶然的:如果您有一个对象,并且仅知道它是AgeFactor ,那么将使用该字段的AgeFactor版本。

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. 这种设计的更合理的版本可能是只包含一个名为factor字段,并将其设置在每个类的构造函数中。

AgeFactor is a class not an interface . AgeFactor是一个类,而不是一个接口 Thus it (AgeFactor) has its own instance variables. 因此,它(AgeFactor)具有自己的实例变量。 Sub-classes (such as young) have their own instance variables. 子类(例如young)具有其自己的实例变量。 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. 一种实现所需功能的方法是使用“ getFactor”方法使AgeFactor成为接口。 Each of the sub classes would implement a getFactor() method which returns the desired constant. 每个子类都将实现getFactor()方法,该方法返回所需的常数。

Note that in java unlike c++ class casts DO NOT change object reference values - so method references are preserved across casts. 请注意,在Java中,与c ++类强制转换不同,请勿更改对象引用值-因此,方法引用将在强制转换之间保留。 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. 还要注意,在Java中,泛型完全是编译时构造。 Via a process known as erasure, the code is compiled without any reference to the 'generic'. 通过被称为擦除的过程,无需任何“通用”引用即可编译代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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