调用超类方法而不是子类方法
A superclass method is called instead of the subclass method
让我们看一下这段代码:
public class ParentClass {
public void foo(Object o) {
System.out.println("Parent");
}
}
public class SubClass extends ParentClass {
public void foo(String s) {
System.out.println("Child");
}
public static void main(String args[]) {
ParentClass p = new SubClass();
p.foo("hello");
}
}
我预计这会打印出 "Child",但结果是 "Parent"。为什么 java 调用 super class 而不是,我该怎么做才能让它调用 subclass 中的方法?
SubClass#foo()
不会覆盖 ParentClass#foo()
因为它没有相同的形式参数。一个拿Object
,一个拿String
。因此,运行时的多态性不适用,也不会导致子类方法执行。来自 Java Language Specification:
An instance method m<sub>C</sub>
declared in or inherited by class C, overrides from C another method m<sub>A</sub>
declared in class A, iff all of the following are true:
A is a superclass of C.
C does not inherit m<sub>A</sub>
.
The signature of m<sub>C</sub>
is a subsignature (§8.4.2) of the signature of m<sub>A</sub>
.
...
并且this section定义方法签名:
Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.
The signature of a method m<sub>1</sub>
is a subsignature of the signature of a method m<sub>2</sub>
if either:
m<sub>2</sub>
has the same signature as m<sub>1</sub>
, or
the signature of m1
is the same as the erasure (§4.6) of the signature of m<sub>2</sub>
.
父 class 没有带有签名 public void foo(String s)
的方法。因此,在编译时,编译器只能选择public void foo(Object o)
方法来执行p.foo("hello")
。
由于子class没有覆盖这个方法(它没有相同的参数类型),父class的foo
方法是被执行的在运行时。
字符串是 java 中的对象,如前所述,它不会被覆盖,但是当您传递一个字符串时,它将 运行 第一个可以作为参数的可用方法,在这种情况下它是 super -class的方法。
让我们看一下这段代码:
public class ParentClass {
public void foo(Object o) {
System.out.println("Parent");
}
}
public class SubClass extends ParentClass {
public void foo(String s) {
System.out.println("Child");
}
public static void main(String args[]) {
ParentClass p = new SubClass();
p.foo("hello");
}
}
我预计这会打印出 "Child",但结果是 "Parent"。为什么 java 调用 super class 而不是,我该怎么做才能让它调用 subclass 中的方法?
SubClass#foo()
不会覆盖 ParentClass#foo()
因为它没有相同的形式参数。一个拿Object
,一个拿String
。因此,运行时的多态性不适用,也不会导致子类方法执行。来自 Java Language Specification:
An instance method
m<sub>C</sub>
declared in or inherited by class C, overrides from C another methodm<sub>A</sub>
declared in class A, iff all of the following are true:
A is a superclass of C.
C does not inherit
m<sub>A</sub>
.The signature of
m<sub>C</sub>
is a subsignature (§8.4.2) of the signature ofm<sub>A</sub>
....
并且this section定义方法签名:
Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.
The signature of a method
m<sub>1</sub>
is a subsignature of the signature of a methodm<sub>2</sub>
if either:
m<sub>2</sub>
has the same signature asm<sub>1</sub>
, orthe signature of
m1
is the same as the erasure (§4.6) of the signature ofm<sub>2</sub>
.
父 class 没有带有签名 public void foo(String s)
的方法。因此,在编译时,编译器只能选择public void foo(Object o)
方法来执行p.foo("hello")
。
由于子class没有覆盖这个方法(它没有相同的参数类型),父class的foo
方法是被执行的在运行时。
字符串是 java 中的对象,如前所述,它不会被覆盖,但是当您传递一个字符串时,它将 运行 第一个可以作为参数的可用方法,在这种情况下它是 super -class的方法。