Java 中的四级继承
Four level Inheritance in Java
我一直在努力理解 java 的一些使用继承来计算输出的代码。代码如下:
class A
{
public int calc(double num) {
System.out.println("calc de A");
return (int)(num+1);
}
}
class B extends A
{
public int calc(long num) {
System.out.println("calc de B");
return (int)(num+2);
}
}
class C extends B
{
public int calc(int num) {
System.out.println("calc de C");
return num+3;
}
}
class D extends C
{
public int calc(float num) {
System.out.println("calc de D");
return (int)(num+4);
}
}
class Main
{
public static void main(String[] args)
{
int num1 = 10;
long num2 = num1;
A a1 = new D();
A a2 = new D();
int result = a1.calc(num1) + a2.calc(num2);
System.out.println("Numero: "+ result);
}
}
我和我的朋友们认为控制台的输出应该是:
calc de C
calc de B
Numero: 25
但是我们运行在Eclipse和Ideone(link:http://ideone.com/CTdklv)中测试了一下,给出的答案是
calc de A
calc de A
Numero: 22
如果方法的签名不同,谁能解释为什么输出是 22。
我们认为,如果您使用 int 作为参数调用 calc 方法,您应该转到 B class 的 calc 方法,而不是 A class.
感谢您的帮助!
谢谢。
在Java中,可以调用哪些重载是由引用变量的类型决定的(15.12.1):
If the form (of the method invocation expression) is ExpressionName . [TypeArguments] Identifier, then the class or interface to search is the declared type T of the variable denoted by ExpressionName if T is a class or interface type, or the upper bound of T if T is a type variable.
因为 a1
和 a2
被声明为 A
,你可以给它们分配一个 D
但你只能从 [=15= 调用方法].
如果稍微更改一下类型,您会发现它是这样工作的:
class A {
void m(int i) {}
}
class B extends A {
void m(double d) {}
}
A a = new B();
double d = 0d;
a.m(d); // won't compile
// will say something like
// 'double can not be converted to int'
因此,如果您将 a1
和 a2
更改为 D
D a1 = new D();
D a2 = new D();
输出应该如您所料,因为 B
、C
和 D
中的重载可供调用。
请注意,它也适用于覆盖。
class A {
protected void m() {}
}
class B extends A {
@Override
public void m() {}
}
// in another package...
B b = new B();
b.m(); // call m because it is public in B
A a = b;
a.m(); // won't compile because it is protected in A
哪些方法可用取决于引用的类型。
我一直在努力理解 java 的一些使用继承来计算输出的代码。代码如下:
class A
{
public int calc(double num) {
System.out.println("calc de A");
return (int)(num+1);
}
}
class B extends A
{
public int calc(long num) {
System.out.println("calc de B");
return (int)(num+2);
}
}
class C extends B
{
public int calc(int num) {
System.out.println("calc de C");
return num+3;
}
}
class D extends C
{
public int calc(float num) {
System.out.println("calc de D");
return (int)(num+4);
}
}
class Main
{
public static void main(String[] args)
{
int num1 = 10;
long num2 = num1;
A a1 = new D();
A a2 = new D();
int result = a1.calc(num1) + a2.calc(num2);
System.out.println("Numero: "+ result);
}
}
我和我的朋友们认为控制台的输出应该是:
calc de C
calc de B
Numero: 25
但是我们运行在Eclipse和Ideone(link:http://ideone.com/CTdklv)中测试了一下,给出的答案是
calc de A
calc de A
Numero: 22
如果方法的签名不同,谁能解释为什么输出是 22。
我们认为,如果您使用 int 作为参数调用 calc 方法,您应该转到 B class 的 calc 方法,而不是 A class.
感谢您的帮助! 谢谢。
在Java中,可以调用哪些重载是由引用变量的类型决定的(15.12.1):
If the form (of the method invocation expression) is ExpressionName . [TypeArguments] Identifier, then the class or interface to search is the declared type T of the variable denoted by ExpressionName if T is a class or interface type, or the upper bound of T if T is a type variable.
因为 a1
和 a2
被声明为 A
,你可以给它们分配一个 D
但你只能从 [=15= 调用方法].
如果稍微更改一下类型,您会发现它是这样工作的:
class A {
void m(int i) {}
}
class B extends A {
void m(double d) {}
}
A a = new B();
double d = 0d;
a.m(d); // won't compile
// will say something like
// 'double can not be converted to int'
因此,如果您将 a1
和 a2
更改为 D
D a1 = new D();
D a2 = new D();
输出应该如您所料,因为 B
、C
和 D
中的重载可供调用。
请注意,它也适用于覆盖。
class A {
protected void m() {}
}
class B extends A {
@Override
public void m() {}
}
// in another package...
B b = new B();
b.m(); // call m because it is public in B
A a = b;
a.m(); // won't compile because it is protected in A
哪些方法可用取决于引用的类型。