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
Java: Extending inner classes
提问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 toString
override, 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 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:
馅饼.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.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
顺便说一下,它不会覆盖)。
Extending Pie
with ApplePie
and extending Pie.Slice
with ApplePie.Slice
doesn't change this. The new Slice(startAngle)
in the above code does not magically switch to instantiating something different.
扩展Pie
与ApplePie
和扩大Pie.Slice
与ApplePie.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.toString
is 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 的实例,它应该可以工作。