10

Java で内部クラスを拡張することを理解しようとしています。私は周りを読みましたが、私の質問に完全に答えるものは何も見つかりませんでした。だからここに行きます...

私は持っている...

public class Pie{
    protected Slice[] slices;

    // Pie constructor
    public Pie(int n){
         sliceGenerator(n)
    }

    private void sliceGenerator(int n){
         slices = new Slice[n];
         final float sweepAngle = 360.0f/(float)n;
         float startAngle = 0;
         for (int i=0;i<n;i++){ 
             slices[i] = new Slice(startAngle);
             startAngle += sweepAngle;
         }
    }

    @Override
    public String toString(){
         for (Slice s:slices){  
             s.toString();
         }
    }

    // Inner class...
    public class Slice{
        public Slice(float startAngle){
             //set some private fields based on startAngle and generic pie 
        }

        @Override
        public String toString(){
             return **string based on private fields**
        }
    }
}

それから私はこれを伸ばします...

public class ApplePie extends Pie{
    protected Slice[] slices;

    // Apple Pie constructor
    public ApplePie(int n){
         super(n);
    }

    // Inner class...
    public class Slice extends Pie.Slice{
        public Slice(float startAngle){
            super(startAngle);
            //set some **additional** private fields based on startAngle **specific to apple pie** appleness or something
        }

        @Override
        public String toString(){
             return **string based on apple pie specific private fields**
        }
    }
}

さて、アップルパイを作ってその toString メソッドを呼び出すと、次のようになります...

ApplePie ap = new ApplePie(8);
System.out.println(ap.toString());

アップル パイのスライスに関する情報は取得しませんが、パイのスライスに関する情報は取得します。私のtoStringオーバーライドを無視するか、おそらく私のアップルパイを無視しますSlice。アップルパイのスライスが参照するように配置するにはどうすればよいApplePieですか?

どんな助けでも大歓迎です!パイの参照については申し訳ありません-それは私が取り組んでいる実際のクラスです...

4

3 に答える 3

6

要件を満たすようにコードを変更しました。

スーパークラスPieはの新しいインスタンスを作成しようとしていますが、子クラスApplePieのSliceはそのスーパークラスのメソッドをSliceオーバーライドしません。Slice

子クラスが独自のを作成できるように、以下の関数を追加しましたSlice

protected void newSliceArray(int n) {
    slices = new Slice[n];
}

protected Slice newSlice(float startAngle) {
    return new Slice(startAngle);
}

Pie.java:

public class Pie {
  private int a = 1;
  protected Slice[] slices;

  // Pie constructor
  public Pie(int n) {
    sliceGenerator(n);
  }

  private void sliceGenerator(int n) {
    newSliceArray(n);
    final float sweepAngle = 360.0f / n;
    float startAngle = 0;
    for (int i = 0; i < n; i++) {
      slices[i] = newSlice(startAngle);
      startAngle += sweepAngle;
    }
  }

  protected void newSliceArray(int n) {
    slices = new Slice[n];
  }


  protected Slice newSlice(float startAngle) {
    return new Slice(startAngle);
  }

  @Override
  public String toString() {
    String t = "";
    for (Slice s : slices) {
      t += s.toString();
    }
    return t;
  }

  // Inner class...
  public class Slice {
    public Slice(float startAngle) {
      // set some private fields based on startAngle and generic pie
    }

    @Override
    public String toString() {
      return "" + a;
    }
  }
}

ApplePie.java:

public class ApplePie extends Pie {
  private int b = 2;

  // protected Slice[] slices;

  // Apple Pie constructor
  public ApplePie(int n) {
    super(n);
  }

  protected void newSliceArray(int n) {
    slices = new Slice[n];
  }

  protected Slice newSlice(float startAngle) {
    return new Slice(startAngle);
  }

  // Inner class...
  public class Slice extends Pie.Slice {
    public Slice(float startAngle) {
      super(startAngle);
      // set some **additional** private fields based on startAngle **specific to apple pie**
      // appleness or something
    }

    @Override
    public String toString() {
      return b + "";
    }
  }
}

テスト:

public static void main(String[] args) {
    ApplePie ap = new ApplePie(8);
    System.out.println(ap.toString());
}

コードは印刷されます22222222

于 2013-01-26T06:36:15.767 に答える
3

Pie.Sliceスーパークラスでは、オブジェクトを作成して保存しています。

private void sliceGenerator(int n){
     slices = new Slice[n];
     final float sweepAngle = 360.0f/(float)n;
     float startAngle = 0;
     for (int i=0;i<n;i++){ 
         slices[i] = new Slice(startAngle);
         startAngle += sweepAngle;
     }
}

これらは、によって使用されているのと同じオブジェクトですPie.toString(ApplePieちなみに、これはオーバーライドされません)。

で拡張PieApplePieて拡張Pie.Sliceしても、ApplePie.Sliceこれは変わりません。上記new Slice(startAngle)のコードでは、魔法のように別のインスタンス化に切り替わることはありません。

それを除けば、あなたPie.toString()は何も返していません-コンパイルさえすべきではありません:

@Override
public String toString(){
     for (Slice s:slices){  
         s.toString();
     }
}

すべてのスライスを表す文字列を返したいと思います。これは、たとえば次のような簡単な解決策です。

@Override
public String toString() {
     return Arrays.toString(slices);
}

(Arrays.toString配列を表す文字列を取得するための単なるユーティリティ メソッドです。)

于 2013-01-26T06:30:50.980 に答える
1

答えはあなたのプログラムの中にあります。Sliceクラスをインスタンス化すると、スーパークラスが呼び出され、sliceGeneratorが呼び出されます。このメソッドは、ApplePie.SliceではなくPie.Sliceのインスタンスを内部的に作成します。これを回避するには、sliceGeneratorメソッドを保護し、Apple.Sliceクラスでオーバーライドします。Apple.Sliceのインスタンスを作成すると、機能するはずです。

于 2013-01-26T06:41:22.890 に答える