Java-父类正在从子类调用方法?
对不起,我对编码还是新手,可能还没有把所有的术语都记下来。希望你能理解我的问题。我想要得到的输出是:Java-父类正在从子类调用方法?,java,inheritance,overriding,parent-child,super,Java,Inheritance,Overriding,Parent Child,Super,对不起,我对编码还是新手,可能还没有把所有的术语都记下来。希望你能理解我的问题。我想要得到的输出是: "Cost for Parent is: 77.77" "Cost for Child is: 33.33" 然而,我得到的是: "Cost for Parent is: 33.33" "Cost for Child is: 33.33" 有人能理解为什么吗?下面我有一个简化版的代码,但它背后的逻辑保持不变 public class Parent{ public double cal
"Cost for Parent is: 77.77"
"Cost for Child is: 33.33"
然而,我得到的是:
"Cost for Parent is: 33.33"
"Cost for Child is: 33.33"
有人能理解为什么吗?下面我有一个简化版的代码,但它背后的逻辑保持不变
public class Parent{
public double calculateCost(){
return 77.77;
}
@Override
public String toString(){
return "Cost for Parent is: " + calculateCost();
}
}
public class Child extends Parent{
@Override
public double calculateCost(){
return 33.33;
}
@Override
public String toString(){
return super.toString() + "\nCost for Child is: " + calculateCost();
}
public static void main(String[] args){
Child child1 = new Child();
System.out.println(child1.toString());
}
}
在我看来,子类中的toString()应该从父类调用toString()(因此,从父类调用calculateCost()),然后使用子类的calculateCost()添加到它。我猜super.toString()中的super不适用于它包含的calculateCost()
另外,我知道我可以通过在子类中编写toString()来解决这个问题,如下所示:
@Override
public String toString(){
return "Cost for Parent is: " + super.calculateCost() + "\nCost for Child is: " + calculateCost();
}
但关键是我不想重复代码,我宁愿添加到我正在重写的前一个toString()方法中。请帮助或指导我(不确定我应该搜索什么…)谢谢 请注意,您正在toString方法中调用calculateCost()。因此,将调用孩子的calculateCost()。您可以考虑使用孩子的ToStin函数如下:
class Parent{
public double calculateCost(){
return 77.77;
}
@Override
public String toString(){
return "Cost for Parent is: " + calculateCost();
}
}
class Child extends Parent{
@Override
public double calculateCost(){
return 33.33;
}
@Override
public String toString(){
return "Cost for Parent is: " + super.calculateCost() + "\nCost for
Child is: " + calculateCost();
}
}
calculateCost
在子类中被重写。因此,当从子对象调用super.toString()
时,super.toString()
中的calculateCost()
将是子对象的calculateCost
您必须将super.calculateCost()
显式地放在子类中,以调用父类的calculateCost
,我认为,为此,您最好使用调试模式,以便更好地了解它的工作原理。在阅读您的代码后,我了解您希望它如何运行
但我认为如何实现@Override注释存在问题。注释的含义
@Override annotation是为了实现一个新的
从父类重写
在这种情况下,将不使用父类的public double calculateCost()
,因为您覆盖了子类的calculateCost
我希望我已经解释清楚了。但在这种情况下,您需要做的是更多地研究@Override并了解它是如何工作的。最好的方法是创建父对象和子对象。从child的toString方法中删除super.toString,则会得到相同的结果:
public class Parent{
double cost = 77.77;
public double calculateCost(){
return cost;
}
@Override
public String toString(){
return "Cost for Parent is: " + this.calculateCost();
}
}
public class Child extends Parent{
@Override
public double calculateCost(){
return 33.33;
}
@Override
public String toString(){
return "\nCost for Child is: " + calculateCost();
}
public static void main(String[] args){
Parent parent = new Parent();
Child child1 = new Child();
System.out.println(parent.toString() + child1.toString());
}
}
印刷品:
Cost for Parent is: 77.77
Cost for Child is: 33.33
这是java中的升级。
如果子类和父类都有一个方法,那么将执行子类。如果没有,则将执行父类,尽管您调用了toString方法,包括calculateCost
Cost for Parent is: 77.77
Cost for Child is: 33.33
方法,但实际上是子类中的calculateCost方法
您可以按如下方式修改代码:
父类
public class Parent{
public double calculateCostParent(){
return 77.77;
}
public String toString(){
return "Cost for Parent is: " + calculateCostParent();
}
}
儿童班
public class Child extends Parent{
public double calculateCost(){
return 33.33;
}
@Override
public String toString(){
return super.toString() + "\nCost for Child is: " + this.calculateCost();
}
public static void main(String[] args){
Child child1 = new Child();
System.out.println(child1.toString());
}
}
输出
Cost for Parent is: 77.77
Cost for Child is: 33.33
然后,您可以避免父类和子类同时具有相同名称的相同方法。您可以根据实际类型确定调用重写方法的最佳匹配。在本例中,您有一个子对象的实例。因此,当您在重写或非重写的实例方法中调用重写的方法时,您将看到Child
的实现。换句话说,
Parent p = new Child();
System.out.println(p);
将给出相同的结果。在这些情况下,我决定在父类中放置一个前缀为下划线的私有函数,以便能够针对该特定函数,并且在父实现中仍然具有通用的公共可重写函数
public class Parent{
public double calculateCost(){
return _calculateCost();
}
// Add this parent specific implementation
private double _calculateCost(){
return 77.77;
}
@Override
public String toString(){
return "Cost for Parent is: " + _calculateCost();
}
}
public class Child extends Parent{
@Override
public double calculateCost(){
return 33.33;
}
@Override
public String toString(){
return super.toString() + "\nCost for Child is: " + calculateCost();
}
public static void main(String[] args){
Child child1 = new Child();
System.out.println(child1.toString());
}
}
我认为这是因为JVM的行为,因为在Java中,每当我们调用一个对象上的方法时(该对象属于从其他类继承的类),JVM都会检查该方法是否被该子类重写,所以尽管调用计算成本()的子类重写了toString()方法解析为子类的版本。此外,我知道我可以通过在子类中编写toString()来绕过它,如下所示:这就是实现它的方法。有时我们不能总是得到我们想要的。重写的意义是什么?问题是您已经在Child
中重写了calculateCost()
,因此Parent
中对calculateCost()
的所有引用现在都调用Child
的实现。这就是继承的工作原理。如果父项
需要有一个与子项
不同的成本,则子项
不应从父项
继承。相反,Child
应该包含对Parent
实例的引用。谢谢大家!我认为普遍的共识是,我需要在Child的toString()方法中显式调用super.calculateCost(),这样它才能工作,因为没有办法绕过它。Child
的calculateCost()
覆盖了父项的仅仅因为它存在,而不是因为@Override
注释@Override
本身不起任何作用,它严格地为编译器和程序员提供信息。感谢您的澄清。我被教错了。@Almosta初学者,想详细说明一下吗?它将打印33.33。@Almosta初学者,我们实际上同意这一点。我是说上面的代码会给出同样的不希望的结果,也就是33.33。这是我示例中实际(不明显)类型的值;是吗?您引入了一个新的父类
实例,它与子类
没有任何关系,只是为了获得所需的输出。我想我会这样做。我想,既然Child中的toString()应该本质上显示与Parent中的toString()相同的内容,但只是稍微多了一点,所以我希望会有