无法在 Java 中的匿名内部类中定义额外的方法



Anonymous Inner Class中定义额外的方法(不覆盖超类方法)时,代码编译良好,没有任何问题,但是如果我尝试调用额外的方法,它会抛出错误。那么是否只能在使用anonymous inner class扩展时在子类中override方法?如果是这样,任何人都可以解释我为什么?

这是我的代码的样子

class SomeClass {
public static void main(String[] args) {
SomeOtherClass a = new SomeOtherClass() {
@Override 
public void methodFromSuperClass() {
System.out.println("Method from super class!");
}
public void subClassMethod() {
System.out.println("Sub class method");
}
};
a.methodFromSuperClass(); //This works fine
a.subClassMethod(); // But calling this extra method throws an error

}
}

这是我收到的错误

SomeClass.java:20: error: cannot find symbol
a.subClassMethod();
^
symbol:   method subClassMethod()
location: variable a of type SomeOtherClass
1 error

这种情况与匿名类有一个名称完全相同:

class SomeOtherClass {
public void methodFromSuperClass() { }
}
class Subclass extends SomeOtherClass {
@Override 
public void methodFromSuperClass() {
System.out.println("Method from super class!");
}
public void subClassMethod() {
System.out.println("Sub class method");
}    
}

你做到了:

SomeOtherClass a = new Subclass();
a.subClassMethod();

难道你不同意你不能在这里打电话给subClassMethod吗?毕竟,编译器知道aSomeOtherClass类型,但不知道它是SomeOtherClass的哪个子类。它不会分析你的代码那么久远,看看你是否实际为它分配了一个Subclass实例。

匿名类的情况基本相同。只是这一次,子类在你的代码中没有名字,但它仍然是一个子类,"编译器不会分析你的代码那么久远"的推理同样适用。

由于匿名子类没有名称,因此您不能像命名子类示例中那样执行类似Subclass a = new Subclass();的操作,但是从Java 10开始,您可以执行以下操作:

var a = new SomeOtherClass() { ... };

var允许编译器为您推断变量的类型,而无需您说出类型名称。编译器将推断匿名子类为a的类型,这将允许您执行以下操作:

a.subClassMethod();

最后,完全允许在匿名类中声明额外的成员 - 从匿名类或本地范围以外的任何地方访问它们相当困难,因为匿名类没有名称。声明额外的成员有时仍然很有用,因为例如,您可以在重写的方法中访问它们。

你的假设是正确的。无法以这种方式调用未重写的方法。 考虑一个示例,其中声明了一个接口并使用具体类实例化了它,那么您仍然只能访问接口中定义的方法,而不能访问类中定义的方法。

public interface MyInterface{
public void someMethod();
}
public class MyImpl implements MyInterface{
//someMethod() implementation
// ...
// newMethod()
public void newMethod(){
//some implementation
}
}
public class Main{
public static void main(String[] args){
MyInterface inter = new MyImpl();
inter.someMethod(); // this call is ok
inter.newMethod();  // this call leads to a Symbol not found Exception, 
// because MyInterface has no method named newMethod...
}
}

希望现在更清楚这是什么意思

最新更新