我有这种情况:
public class A
{
private final Integer index;
public Integer getIndex() { return index; }
public static class B
{
//unimportant
}
}
public class C extends B
{
//how to reference getIndex() here?
}
如何在C类的主体中调用getIndex()?
答案 0 :(得分:3)
奇怪的场景......但你必须将C级移动到A级内部的类内部。耸肩?好奇为什么你要扩大一个内部阶级?造成这种情况的设计有哪些限制?根本没有评判你。了解设计背后的想法可能有助于找到替代解决方案。
public class A
{
// make sure final value is set here or in constructor
private final Integer index = 0;
public Integer getIndex() { return index; }
public static class B
{
//unimportant
}
//Doesn't make much sense... but...
public class C extends B
{
//can now call getIndex()
public void callGetIndex() {
getIndex();
}
}
}
奖金研究: 对于那些可能像我一样好奇的人,并考虑使用它来引用另一个文件中的函数。如果您在另一个文件中编译C,并尝试使用封闭的此来访问getIndex:
A.this.getIndex();
可悲的是,这不起作用,因为即使C扩展了B,它仍然需要被A包围才能使该方法起作用。您收到此编译时错误:
C.java:5: error: not an enclosing class: A
A.this.getIndex();
^
1 error
嘿酷!另一个答案,基于@ mzl的答案: 有趣的是,你可以保持B静态并扩展两个类以获得你想要做的事情。例如,如果您无法编辑文件A.java,这很有用,因为A.java是第三方功能。 (在这里给@mzl提供他的回答)
以下是你如何做到这一点! (通过javac A.java C.java测试此编译)
<强> A.java 强>
public class A
{
private final Integer index = 0;
public Integer getIndex() { return index; }
public static class B
{
//unimportant
}
}
C.java
public class C extends A
{
public class D extends A.B {
//can now call getIndex()
public void callGetIndex() {
getIndex();
}
}
}
我创建了一个静态溢流项目,证明了@ mzl的理论: https://github.com/davethomas11/stackoverflow_Q_39441077
一个哥特式。您会注意到我在D之前创建了一个C实例,以确保可以访问getIndex()。我没有测试如果直接实例化D会发生什么,我会稍后再这样做并发布结果。
该实例化D的后期更新直接测试。
我在静态主函数中添加了C.D testD = new C.D();
:
$ sh build.sh
StackOverflowQuestion39441077.java:5: error: an enclosing instance that contains C.D is required
C.D testD = new C.D();
^
1 error
编译器帮助我们不要让我们这样做。
答案 1 :(得分:1)
如果你想扩展(非静态地)内部类,你必须扩展外部类。
你可以这样做:
public class A
{
private final Integer index;
public Integer getIndex() { return index; }
public static class B {}
}
public class D extends A{
public class C extends B{}
}
答案 2 :(得分:0)
你做不到。 C
扩展了B
,但没有getIndex()
方法。 C
必须扩展A
才能继承该方法。
答案 3 :(得分:0)
(我觉得这是一个有趣的理论问题,但在实践中没什么意义。)
A.getIndex
您无法访问B
,因为B
是静态的,getIndex
不是,所以要调用您需要的getIndex
A
的非空实例。
假设你可以使B
非静态,你也不能,因为你的方案变得矛盾:
B
是内部的,因此要实例化一个新对象,需要先前的A
非空实例:A a=new A(); B b=a.new B();
C
是顶级(非内部)类,因此可以直接实例化。但是,作为B
的子类,它受到与其超类相同的限制:它需要A
的实例。矛盾!我认为让它发挥作用的唯一方法是声明getIndex
静态,因此不需要A
的实例(事实上,它们都不是{{}}的子类化1}}会有问题。)