0

私はジェネリックと本当に混乱しています。私の状況を助けてください:

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;
}

上記のコードでは、参照M mAgeFactor実行時に指定した型を参照しています。次の方法で呼び出すとします。

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

階層は次のとおりです。

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 + " ";

    }
}

私が知りたいのは、なぜのフィールドm.factorを参照するのか?? または実行時に指定するタイプを参照する必要があります。AgeFactorfactorm.factoryoungpro

m が実際に AgeFactor を参照している場合、ポリモーフィズムはフィールドに適用されないため、m.factor は常に AgeFactor の因子を参照することを理解しています。もしそうなら、ジェネリックの必要性は何ですか?Javaのジェネリックはそれ自体がジェネリックですか? ジェネリックを乗り越えるのを手伝ってください。

4

2 に答える 2

3

フィールドは、メソッドのようにオーバーライドされません。この種のポリモーフィズムが必要な場合は、フィールドではなくメソッドで行う必要があります。

ここでは、experiencedproという名前の 2 つの異なるフィールドがありますfactor。1 つは からAgeFactor、もう 1 つはexperiencedとからproです。同じ名前を持つという事実は完全に偶然です。オブジェクトがあり、それについて知られているのはそれが であるということだけである場合、そのフィールドAgeFactorAgeFactorバージョンが使用されます。

この設計のより賢明なバージョンは、 という名前factorのフィールドを 1 つだけ持ち、各クラスのコンストラクターで設定することです。

于 2013-07-15T20:07:11.627 に答える
0

AgeFactor はインターフェースではなくクラスです。したがって、(AgeFactor) には独自のインスタンス変数があります。サブクラス (young など) には、独自のインスタンス変数があります。サブクラスのインスタンス変数は、サブ/スーパー インスタンス変数から完全に分離されています。前述のように、非静的メソッドのみがポリモーフィズムに参加します (つまり、サブクラスはスーパー クラスのメソッドをオーバーライドできます)。あなたが望むことを行う1つの方法は、AgeFactorを「getFactor」メソッドを持つインターフェースにすることです。各サブクラスは、目的の定数を返す getFactor() メソッドを実装します。

Java では、C++ クラスのキャストとは異なり、オブジェクト参照値を変更しないことに注意してください。そのため、メソッド参照はキャスト間で保持されます。以下を試してください:

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 + " ";

      }
  }
}

また、Java では、ジェネリックは完全にコンパイル時の構成要素であることに注意してください。消去と呼ばれるプロセスを介して、コードは「ジェネリック」への参照なしでコンパイルされます。

于 2013-07-15T21:15:57.037 に答える