Java:扩展内部类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14534421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 16:34:33  来源:igfitidea点击:

Java: Extending inner classes

javaclassinheritanceextends

提问by Jon

I am trying to understand extending inner classes in Java. I have read around but nothing I found quite answers my question. So here goes...

我试图理解在 Java 中扩展内部类。我已经阅读过,但我发现没有什么能完全回答我的问题。所以这里...

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...

现在,当我制作一个苹果派并调用它的 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 toStringoverride, or more likely ignores my apple pie Slice. How can I arrange it such that apple pie slices refer to ApplePie?

我没有得到关于苹果馅饼切片的信息,但是关于馅饼切片的信息。它忽略我的toString覆盖,或者更有可能忽略我的 apple pie Slice。我该如何安排它,以便苹果派切片参考ApplePie

Any help much appreciated! Sorry for pie references - it is the actual class I am working with...

非常感谢任何帮助!对不起,馅饼参考 - 这是我正在使用的实际课程......

采纳答案by farmer1992

I've changed your code to meet your requirements.

我已更改您的代码以满足您的要求。

Your super class Pieis about to create a new instance of Slice, but the child class ApplePie's Slice does not override the Slicemethod 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:

馅饼.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:

苹果派.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

回答by Paul Bellora

In your superclass, you are creating and storing Pie.Sliceobjects:

在您的超类中,您正在创建和存储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 ApplePiedoesn't override by the way).

这些是正在使用的相同对象Pie.toStringApplePie顺便说一下,它不会覆盖)。

Extending Piewith ApplePieand extending Pie.Slicewith ApplePie.Slicedoesn't change this. The new Slice(startAngle)in the above code does not magically switch to instantiating something different.

扩展PieApplePie和扩大Pie.SliceApplePie.Slice不会改变这一点。在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. This would be a quick solution for example:

我猜你想返回一个代表所有切片的字符串。这将是一个快速解决方案,例如:

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

(Arrays.toStringis just a utility method to get a String representing of an array.)

Arrays.toString只是获取表示数组的字符串的实用方法。)

回答by CuriousMind

The answer lies within your program. When you instantiate Slice class, it gives call to the super class and invokes sliceGenerator. This method internally creates instances of Pie.Slice and not ApplePie.Slice. To get around this, make sliceGenerator method protected and override it in Apple.Slice class. Create the instances of Apple.Slice and it should work.

答案就在您的程序中。当您实例化 Slice 类时,它会调用超类并调用 sliceGenerator。此方法在内部创建 Pie.Slice 而不是 ApplePie.Slice 的实例。要解决此问题,请保护 sliceGenerator 方法并在 Apple.Slice 类中覆盖它。创建 Apple.Slice 的实例,它应该可以工作。