由于对象是子类,程序如何决定运行哪个方法



所以我有以下代码:

import java.util.Scanner;
class Shape{
double length, breadth;
Shape(double l, double b) { //Constructor to initialize a Shape object  
length = l;
breadth = b;
}
Shape(double len) { //Constructor to initialize another Shape object  
length = breadth = len;
}
double calculate(){ // To calculate the area of a shape object
return length * breadth ;
}
}
public class Test1 extends Shape {
double height;
Test1(double l, double h) {
super(l);
height = h;
}
Test1(double l, double b, double h) {
super(l, b);
height = h;
}
@Override
double calculate(){
return length*breadth*height;
}   
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
double l=sc.nextDouble();
double b=sc.nextDouble();   
double h=sc.nextDouble(); 

Test1 myshape1 = new Test1(l,h);
Test1 myshape2 = new Test1(l,b,h);

double volume1;
double volume2;

volume1 = myshape1.calculate();
volume2 = myshape2.calculate();

System.out.println(volume1);
System.out.println(volume2);
}
}

,我不明白它是如何决定运行哪个calculate()方法的,因为它们都是从子类对象调用的,但其中一个决定运行父类方法。

是否与构造函数重载有关?如果是,怎么做?

构造函数重载与哪个方法运行"无关。构造函数仅用于初始化实例,以及"哪个方法运行";可能是与方法重载有关的问题,在您的问题中并非如此。

在两种情况下:

volume1 = myshape1.calculate();
volume2 = myshape2.calculate();

calculate()Test1…→java.lang.Object类层次结构,被调用-在您的情况下是Test1::calculate

您不调用超类的calculate(),而是您的类的calculate()使用继承自超类Shape的字段,如:

double calculate(){
return length*breadth*height;
}

当你实例化一个类时,它是用它的超类的所有成员(甚至是私有的)创建的,这就是为什么你使用超类的字段,就好像它们是在相关的类中定义的一样。

旁注:父类的private成员不能在子类中直接访问。您需要适当的访问器/getter来访问它们。

如果该方法不是privatestaticfinal,则该方法默认为虚方法。

也就是说,将使用最低类的方法。
您已经覆盖了Test1中的方法,所以它将被调用。我建议你把@Override写在一个方法上,向你自己和其他人表明这个方法是继承的。