您是否有充分的理由可以在Java类中拥有或不具有内部接口? (就像你会内心一样)。我无法找到谷歌的确切答案,但看起来好像你不能像使用内部类一样嵌入界面。我的猜测是Java创建者没有看到使其成为可能的一个很好的理由,所以它不是,但也许有很好的理由?
例如我无法将其编译(这是一个大类)
package buttonGetSourceObject;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ClassWithButton implements ActionListener, ButtonOwner{
private String objectName = "";
public ClassWithButton(String string) {
objectName = string;
JFrame f = new JFrame();
JPanel p = new JPanel();
MyJButton b = new MyJButton(this,"Press This Button for Name of Owner of Button");
b.addActionListener(this);
f.add(p);
p.add(b);
f.pack();
f.setVisible(true);
}
public static void main(String[] args){
ClassWithButton c = new ClassWithButton("object1name");
}
@Override
public void actionPerformed(ActionEvent arg0) {
((ButtonOwner)((MyJButton)arg0.getSource()).getOwner()).printInstanceName();
}
public interface ButtonOwner {
public void printInstanceName();
}
private class MyJButton extends JButton {
/**
*
*/
private static final long serialVersionUID = 1L;
Object owner = null;
public Object getOwner() {
return owner;
}
public void setOwner(Object owner) {
this.owner = owner;
}
public MyJButton(Object o, String string){
owner = o;
this.setText(string);
}
}
@Override
public void printInstanceName() {
System.out.println(this);
}
public String getObjectName() {
return objectName;
}
public void setObjectName(String objectName) {
this.objectName = objectName;
}
public String toString(){
return this.getObjectName();
}
} //end
编译器似乎没有将内部接口“ButtonOwner”识别为存在于所有
答案 0 :(得分:5)
因为它是一个内部类,所以您必须使用您正在扩展的类的全名(例如,使用ClassWithButton.ButtonOwner
而不是ButtonOwner
):
public class ClassWithButton implements ActionListener, ClassWithButton.ButtonOwner
然而,这不起作用,因为您正在扩展inner interface:
检测到循环:类型ClassWithButton无法扩展/实现自身或其自己的成员类型之一
至于为什么类不能实现内部接口,对上述问题的评论表明它可能是因为:
类加载如何工作。对其他类的正常引用是懒惰加载的,但外部类,超类和实现的接口在加载类本身之前自动加载。当你的外部类实现一个内部接口并且该构造本身有效时,在运行时加载类时,你会在类加载器中得到一个StackOverflowError ...
答案 1 :(得分:3)
这是一个明确的答案:JLS Chapter 9:
“嵌套接口是任何接口,其声明发生在另一个类或接口的主体内。”
“顶级界面是不是嵌套界面的界面。”
语法在Chapter 18:
ClassBody:
{ { ClassBodyDeclaration } }
ClassBodyDeclaration:
;
{Modifier} MemberDecl
[static] Block
MemberDecl:
...
InterfaceDeclaration
您的代码无法编译的原因是您试图使外部类成为其自身嵌套接口的子类型。 (我找不到禁止这个的JLS部分,但是编译器错误消息表明这是禁止的。)
我不确定“为什么”他们决定禁止扩展内部类或自身接口的类。可能只是因为他们认为所涉及的规范和实施工作超出了允许它的效用。
(在课堂加载过程中防止StackOverflowError
的解释并不成立: