简体   繁体   English

Java:扩展内部类

[英]Java: Extending inner classes

I am trying to understand extending inner classes in Java. 我试图理解在Java中扩展内部类。 I have read around but nothing I found quite answers my question. 我已经阅读过,但没有找到我的问题。 So here goes... 所以这里......

I have... 我有...

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

Then I extend this... 然后我扩展这个......

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

Now, when I make an Apple pie and call its toString method, like so... 现在,当我制作一个Apple派并调用其toString方法时,就像这样......

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

I do not get information about the apple pie slices, but information about the pie slices. 我没有获得有关苹果派切片的信息,但有关馅饼切片的信息。 It ignores my toString override, or more likely ignores my apple pie Slice . 它忽略了我的toString覆盖,或者更可能忽略了我的苹果派Slice How can I arrange it such that apple pie slices refer to ApplePie ? 如何安排苹果派切片参考ApplePie

Any help much appreciated! 任何帮助非常感谢! Sorry for pie references - it is the actual class I am working with... 对不起馅饼参考 - 这是我正在使用的实际课程......

I've changed your code to meet your requirements. 我已经更改了您的代码以满足您的要求。

Your super class Pie is about to create a new instance of Slice , but the child class ApplePie's Slice does not override the Slice method of its super class'. 你的超类Pie即将创建一个新的Slice实例,但是子类ApplePie的Slice不会覆盖其超类的Slice方法。

I added the functions below to enable the child class to create its own Slice . 我添加了下面的函数,以使子类能够创建自己的Slice

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

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

Pie.java: 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: 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 + "";
    }
  }
}

Test: 测试:

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

The code will print 22222222 该代码将打印22222222

In your superclass, you are creating and storing Pie.Slice objects: 在您的超类中,您正在创建和存储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;
     }
}

These are the same objects being used by Pie.toString (which ApplePie doesn't override by the way). 这些是Pie.toString使用的相同对象( ApplePie Pie.toStringApplePie不会覆盖它)。

Extending Pie with ApplePie and extending Pie.Slice with ApplePie.Slice doesn't change this. 扩展PieApplePie和扩展Pie.SliceApplePie.Slice不会改变这一点。 The new Slice(startAngle) in the above code does not magically switch to instantiating something different. 上面代码中的new Slice(startAngle)并没有神奇地切换到实例化不同的东西。

Aside from that, your Pie.toString() isn't returning anything - it shouldn't even compile: 除此之外,你的Pie.toString()没有返回任何东西 - 它甚至不应该编译:

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

I'm guessing you want to return a String representing all the slices. 我猜你想要返回一个表示所有切片的String。 This would be a quick solution for example: 这将是一个快速解决方案,例如:

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

( Arrays.toString is just a utility method to get a String representing of an array.) Arrays.toString只是一个获取表示数组的String的实用方法。)

The answer lies within your program. 答案在于你的计划。 When you instantiate Slice class, it gives call to the super class and invokes sliceGenerator. 当您实例化Slice类时,它会调用超类并调用sliceGenerator。 This method internally creates instances of Pie.Slice and not ApplePie.Slice. 此方法在内部创建Pie.Slice的实例,而不是ApplePie.Slice。 To get around this, make sliceGenerator method protected and override it in Apple.Slice class. 要解决此问题,请使sliceGenerator方法受到保护,并在Apple.Slice类中覆盖它。 Create the instances of Apple.Slice and it should work. 创建Apple.Slice的实例,它应该工作。

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

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