问题描述
在 Anonymous Inner Class
中定义额外方法(不覆盖超类方法)时,代码编译正常,没有任何问题,但如果我尝试调用额外方法,则会引发错误。那么在使用 override
扩展时,是否只能在子类中使用 anonymous inner class
方法?如果是这样,谁能解释一下为什么?
这是我的代码的样子
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
?毕竟,编译器知道 a
是 SomeOtherClass
类型,但不知道它是 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...
}
}
希望现在更清楚这意味着什么