无法在 Java 中的匿名内部 Class 中定义额外方法
Cannot define extra methods in an Anonymous Inner Class in Java
在 Anonymous Inner Class
中定义额外的方法(不覆盖超级 class 方法)时,代码可以正常编译,没有任何问题,但如果我尝试调用额外的方法,则会抛出错误.那么,当使用 anonymous inner class
扩展时,是否只能在子 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 实例化了它,那么你仍然只能访问接口中定义的方法,而不是 class.
中定义的方法
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...
}
}
希望现在更清楚这是什么意思了
这种情况与匿名class有名字完全一样:
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
的哪个子 class。它不会分析您的代码那么久远以查看您是否实际为其分配了 Subclass
的实例。
匿名classes的情况基本相同。只是这一次,subclass在你的代码中没有名字,但它仍然是一个subclass,同样的道理“编译器不会分析你的代码那么早”适用。
由于匿名子class没有名字,你不能像在命名子class例子中做类似Subclass a = new Subclass();
的事情,但是因为Java 10 ,你可以这样做:
var a = new SomeOtherClass() { ... };
var
让编译器为您推断变量的类型,而无需您说出类型名称。编译器会将匿名子 class 推断为 a
的类型,这将允许您执行以下操作:
a.subClassMethod();
最后,完全允许在匿名 classes 中声明额外的成员——只是很难从匿名 class 或本地范围内以外的任何地方访问它们,因为匿名 class 没有名字。声明额外的成员有时仍然有用,因为例如您可以在覆盖的方法中访问它们。
在 Anonymous Inner Class
中定义额外的方法(不覆盖超级 class 方法)时,代码可以正常编译,没有任何问题,但如果我尝试调用额外的方法,则会抛出错误.那么,当使用 anonymous inner class
扩展时,是否只能在子 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 实例化了它,那么你仍然只能访问接口中定义的方法,而不是 class.
中定义的方法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...
}
}
希望现在更清楚这是什么意思了
这种情况与匿名class有名字完全一样:
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
的哪个子 class。它不会分析您的代码那么久远以查看您是否实际为其分配了 Subclass
的实例。
匿名classes的情况基本相同。只是这一次,subclass在你的代码中没有名字,但它仍然是一个subclass,同样的道理“编译器不会分析你的代码那么早”适用。
由于匿名子class没有名字,你不能像在命名子class例子中做类似Subclass a = new Subclass();
的事情,但是因为Java 10 ,你可以这样做:
var a = new SomeOtherClass() { ... };
var
让编译器为您推断变量的类型,而无需您说出类型名称。编译器会将匿名子 class 推断为 a
的类型,这将允许您执行以下操作:
a.subClassMethod();
最后,完全允许在匿名 classes 中声明额外的成员——只是很难从匿名 class 或本地范围内以外的任何地方访问它们,因为匿名 class 没有名字。声明额外的成员有时仍然有用,因为例如您可以在覆盖的方法中访问它们。