Java 内部类扩展外部类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7125179/
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 Inner Class extends Outer Class
提问by amaidment
There are some cases in Java where an inner class extends an outer class.
在 Java 中存在一些内部类扩展外部类的情况。
For example, java.awt.geom.Arc2D.Float is an inner class of java.awt.geom.Arc2D, and also extends Arc2D. (c.f. http://download.oracle.com/javase/6/docs/api/java/awt/geom/Arc2D.Float.html)
例如 java.awt.geom.Arc2D.Float 是 java.awt.geom.Arc2D 的内部类,也是 Arc2D 的扩展类。(参见http://download.oracle.com/javase/6/docs/api/java/awt/geom/Arc2D.Float.html)
Also, sun.org.mozilla.javascript.internal.FunctionNode.Jump extends sun.org.mozilla.javascript.internal.Node, which is a superclass of FunctionNode. (sorry... cannot find a link to the javadoc)
此外,sun.org.mozilla.javascript.internal.FunctionNode.Jump 扩展了 sun.org.mozilla.javascript.internal.Node,它是 FunctionNode 的超类。(抱歉……找不到指向 javadoc 的链接)
To me, this seems odd. Could you then create these?
对我来说,这似乎很奇怪。然后你能创造这些吗?
new Arc2D.Float.Float() //n.b. I couldn't get this to compile in Intellij IDEA;
new FunctionNode.Jump.Jump.Jump(1); // I could get this to compile
What purpose does it serve to have a subclass nested as an inner class of the superclass?
将子类嵌套为超类的内部类有什么目的?
I wondered whether it was to access something in the superclass, but if you wanted to access any variables/methods in the parent, you could use
我想知道是否要访问超类中的某些内容,但是如果您想访问父类中的任何变量/方法,则可以使用
super.variable;
or
或者
super.method();
Edit 1: jjnguy has suggested it's to keep the logic in the same place. In which case, why wouldn't you write a file com.mypackage.AbstractTest:
编辑 1:jjnguy 建议将逻辑保持在同一位置。在这种情况下,你为什么不写一个文件 com.mypackage.AbstractTest:
abstract class AbstractTest {
abstract String getString();
}
class ExtensionTest extends AbstractTest {
@Override
String getString() {
return "hello world";
}
}
... rather than:
... 而不是:
abstract class AbstractTest {
abstract String getString();
class ExtensionTest extends AbstractTest {
@Override
String getString() {
return "hello world";
}
}
}
Edit 2: It has rightly been pointed out that the suggestion in my previous edit was flawed, as couldn't construct ExtensionTest outside of the package. However, I've had a further think about this over the weekend, so what about the following:
编辑 2:正确地指出,我之前编辑中的建议存在缺陷,因为无法在包外构建 ExtensionTest。但是,我在周末进一步考虑了这个问题,那么以下内容呢:
abstract class Test {
public class ExtensionTest extends AbstractTest {
@Override
String getString() {
return "hello world";
}
}
private abstract class AbstractTest {
abstract String getString();
}
}
In essence, the best answer I've seen so far is that having an inner class extend its outer class allows the logic to be grouped together. However, I think that this can be done without the extension.
从本质上讲,到目前为止我看到的最好的答案是让内部类扩展其外部类允许将逻辑组合在一起。但是,我认为这可以在没有扩展的情况下完成。
In my mind, it seems like bad design to have a class that can have an infinite number of the same subclasses nested within it. (Context: this came up whilst trying to produce a dictionary for a code completion utility, and threw a StackOverflowException. I found a workaround, but I just cannot understand why it had been designed that way.)
在我看来,拥有一个可以嵌套无数相同子类的类似乎是一种糟糕的设计。(上下文:这是在尝试为代码完成实用程序生成字典时出现的,并抛出了 StackOverflowException。我找到了一个解决方法,但我无法理解为什么它是这样设计的。)
回答by jjnguy
Have a look at Java's Point2D
. It has two inner classes that are sub-classes of it.
看看 Java 的Point2D
. 它有两个内部类,它们是它的子类。
The important thing to note is that they are static
inner classes. This has an entirely diffenent meaning that a regular inner class. Just like a static method, a static class is defined at the class-level instead of the object level.
需要注意的重要一点是它们是static
内部类。这与常规内部类具有完全不同的含义。就像静态方法一样,静态类是在类级别而不是对象级别定义的。
In the Point2D
case, it is done to logically couple the classes and their logic. It helps a user of the abstract
type Point2D
find an implementation that they can use.
在这种Point2D
情况下,将类和它们的逻辑进行逻辑耦合。它可以帮助该abstract
类型的用户Point2D
找到他们可以使用的实现。
In response to your edit I'd like to point out 1 important fact. A single Java file may only contain one public class, exceptfor public inner classes. While both of your examples may compile, they do not allow access to those classes to the public. If you want to present multiple public classes to someone in a single file, you must use public static inner classes.
针对您的编辑,我想指出 1 个重要事实。一个 Java 文件可能只包含一个公共类,公共内部类除外。虽然您的两个示例都可以编译,但它们不允许公开访问这些类。如果要在单个文件中向某人提供多个公共类,则必须使用公共静态内部类。
回答by Pindatjuh
There are two cases of inner-classes:
内部类有两种情况:
staticinner-classes. The inner-class does notkeep reference to the outer-class.
non-staticinner-classes. The inner-class doeskeep a reference to the outer-class.
静态内部类。该内部类并没有保持参考外类。
非静态内部类。内部类确实保留对外部类的引用。
The case of a static inner-class that extends the outer-class is not as interesting as the non-static inner-class extending the outer-class.
静态内部类扩展外部类的情况不像非静态内部类扩展外部类那么有趣。
What happens with the latter is: to create the inner-class, one needs a reference to the outer-class. However, as the inner-class is an instance of the outer-class, it also accepts a reference to another instance of the inner-class, to be used as outer-class.
后者会发生什么:要创建内部类,需要对外部类的引用。然而,由于内部类是外部类的一个实例,它也接受对内部类的另一个实例的引用,用作外部类。
Let's look at some code:
让我们看一些代码:
Outer a = new Outer();
Outer.Inner b = a.new Inner();
// Only possible when Inner extends Outer:
Outer.Inner c = a.new Inner().new Inner();
If you know the builder pattern, this can be used to have an OOP-version of it:
如果您知道builder pattern,则可以使用它来拥有它的 OOP 版本:
public abstract class Command {
// Not possible to create the command, else than from this file!
private Command() {
}
public abstract void perform();
public static class StartComputer extends Command {
public void perform() {
System.out.println("Starting Computer");
}
}
public class OpenNotepad extends Command {
public void perform() {
Command.this.perform();
System.out.println("Opening Notepad");
}
}
public class ShutdownComputer extends Command {
public void perform() {
Command.this.perform();
System.out.println("Shutting Computer");
}
}
}
Which is used as: new Command.StartComputer().new OpenNotepad().new ShutdownComputer().perform();
.
用作:new Command.StartComputer().new OpenNotepad().new ShutdownComputer().perform();
。
回答by irreputable
There 1st one compiles fine on my IntelliJ.
第一个在我的 IntelliJ 上编译得很好。
Strictly speaking, static member classes are not inner classes. They are called nestedclasses.
严格来说,静态成员类不是内部类。它们被称为嵌套类。