public class A{
public static int x = 1;
public int m(A a, B b){
return a.m(b, b) + x;
}
}
public class B extends A {
public int m(A a1, B a2){
if(a1 == a2)
return x;
return super.m(a1,a2);
}
}
这是我过去考试的一个问题。
public class Main{
public static void main(String[] args){
B b1 = new B(){int m(A a, A b){ return 10; }};
System.out.println(b1.m(b1, b1));
}
}
问题是,以下输出是什么。在1的答案中我是对的。但我没有完全理解为什么。
由于B对象的内部类是(A,A)。我是否正确认为它不能覆盖超级方法m,因为它是(A,B)?如果交换了两个方法的参数,它是否能够覆盖?
既然它既不能覆盖也不能超载,它什么都不做,只是在B类中使用方法m?
对象的内部类是否仅适用于自身?它是不是一个异类?
对所有问题道歉。
提前致谢。
编辑:
从我到目前为止的理解,因为静态类型设置为B,所以类型B无法看到anon类。如果将其设置为公开,则可以看到,但仍然无法使用。
这使我对另一个问题感到困惑。
public class A{
public static int x = 1;
public int m(A a, B b){
return a.m(b, b) + x;
}
}
public class Main{
public static void main(String[] args){
A a1=new A();
A a2=new A(){
int m(A a,B b){
return 10;
}};
B b1=new B();
System.out.println(a1.m(a2,b1));
}
}
调用以下内容时,输出为11。 当调用a1.m时,它传递a2和b1。
在A类中,当调用a.m(b,b)时。它调用动态类型。这是因为一旦解析它会变为动态类型吗?那么现在它可以使用anon类了吗?
答案 0 :(得分:6)
让我们一起浏览JVM:
B b1 = new B(){ int m(A a,A b) { return 10; } };
这将创建B
的实例,其中方法m()
的匿名重载具有两个类型为A
的参数。但这是一个不同的 m()
方法而不是类B
(或A
)定义的方法,因为它们的签名({{1 }} vs A, A
)不同。
然后:
A, B
这会使用System.out.println(b1.m(b1, b1));
类型的两个参数调用b1
的{{1}}方法。
现在JVM查找m()
是什么:
B
有两个m()
类型的参数; m()
中找到匹配项:名称为B
的方法,其第一个参数为B
(因为m()
继承A
)并且第二个参数类型为B
; A
的匿名重载完全被忽略 (参见https://gist.github.com/fge/5762353)因此调用类B
的{{1}}方法。在这种方法中,我们有:
b1
由于条件为真(已使用两个参数作为完全相同的对象引用调用该方法),因此必须返回m()
的值; B
由班级if (a1 == a2) // TRUE!
return x;
定义,班级x
x
:
A
由于这是A类的静态成员(B类不隐藏),因此可以通过实例方法从B
或extends
的任何实例访问它;因此,该程序的返回码和输出为1。
答案 1 :(得分:4)
我认为它不能覆盖超级方法m是正确的,因为它是(A,B)?
是的,你是对的:这会创建一个重载,而不是基类中方法的覆盖。
如果交换了两个方法的参数,是否可以覆盖?
否:要覆盖,方法签名必须完全匹配。
既然它既不能覆盖也不能超载,它什么都不做,只是在B类中使用方法m?
不完全是:(A, B)
重载恰好比(A, A)
重载更具体。
对象的内部类是否仅适用于自身?它是不是一个异类?
如果你传递了一对A
s,你就能调用内部类中的方法。
答案 2 :(得分:1)
这里有几点:
@Override
。 b1
的(静态)类型为B
,因此匿名类型中声明的额外方法不可用。虽然你可以做以下事情:
B b1 = null;
System.out.println(new B(){int m(B a, B b){ return 10; }.m(b1, b1));
或者
final B b1 = null;
new B() {
{
System.out.println(this.m(b1, b1));
}
int m(B a, B b) { return 10; }
};
System.err.println("donkey".toCharArray());
不会调用println(Object)
。Comparable
)中的参数发生时,情况不完全相同。答案 3 :(得分:1)