Java - 父 class 正在调用子 class 的方法?
Java - parent class is calling a method from a child class?
抱歉,我对编码还是个新手,可能没有掌握所有术语。希望您仍然能理解我的问题。我想要得到的输出是:
"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());
}
}
在我看来,子 class 中的 toString() 应该调用父 class 中的 toString() (因此,父 class 中的 calculateCost() ) 然后用 Child 的 calculateCost() 添加到它。我猜 super.toString() 中的 super 不适用于它包含的 calculateCost() 。
另外,我知道我可以通过像这样在 Child class 中编写 toString() 来绕过它:
@Override
public String toString(){
return "Cost for Parent is: " + super.calculateCost() + "\nCost for Child is: " + calculateCost();
}
但重点是我不想重复代码,我宁愿添加到我覆盖的先前 toString() 方法中。请帮助或指导我(不确定我应该用谷歌搜索什么...)谢谢!
请注意,您是在 toString 方法中调用 calculateCost() 。因此 child 的 calculateCost() 被调用。您可以考虑使用 Child 的 toString 函数,如下所示。
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
在 Child
class 中被覆盖。因此,当从 Child
调用 super.toString()
时,super.toString()
中的 calculateCost()
将是 Child
的 calculateCost
.
您必须将 super.calculateCost()
显式放入 Child
class 才能调用 Parent
的 calculateCost
。
我认为为此您可以做的最好的事情是使用调试模式,这样您可以更好地理解它是如何工作的。阅读您的代码后,我了解您希望它如何 运行。
但是我觉得你实现@Override注解的方式有问题。
的意思
@Override annotation is to implement a new method that had been
literally overriding from the parent class.
在这种情况下,不会使用父项 class 的 public double calculateCost()
,因为您覆盖了子项 class 的计算成本。
希望我已经解释清楚了。但是在这种情况下,您需要做的是研究更多 @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 中的向上转换。
如果subclass 和parent class 都有一个方法.then 将执行subclass。如果不是,则将执行 parent class,尽管您调用 toString 方法包括 calculateCost
你的parentclass中的方法,但实际上会执行子class中的calculateCost方法。
您可以修改您的代码如下:
Parent Class
public class Parent{
public double calculateCostParent(){
return 77.77;
}
public String toString(){
return "Cost for Parent is: " + calculateCostParent();
}
}
Child Class
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
那你就可以避免parent和子class同时有相同的同名方法
您可以依赖于根据实际类型调用重写方法的最佳匹配。在这种情况下,您有一个 Child
的实例。因此,当您在重写或非重写实例方法中调用重写方法时,您将看到 Child
的实现。也就是说,
Parent p = new Child();
System.out.println(p);
会给出相同的结果。
我决定在我的父 class 中放置一个带有下划线前缀的私有函数,以便能够针对该特定函数并在我的父中仍然具有通用的 public 可覆盖函数实施。
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 中,每当我们调用一个对象的方法时,它属于 class 继承自其他 class ],JVM 检查该方法是否被 subclass 覆盖,因此尽管从 subclass 覆盖了 toString() 方法,计算 cost() 的调用解析为 subclass'版本。
抱歉,我对编码还是个新手,可能没有掌握所有术语。希望您仍然能理解我的问题。我想要得到的输出是:
"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());
}
}
在我看来,子 class 中的 toString() 应该调用父 class 中的 toString() (因此,父 class 中的 calculateCost() ) 然后用 Child 的 calculateCost() 添加到它。我猜 super.toString() 中的 super 不适用于它包含的 calculateCost() 。
另外,我知道我可以通过像这样在 Child class 中编写 toString() 来绕过它:
@Override
public String toString(){
return "Cost for Parent is: " + super.calculateCost() + "\nCost for Child is: " + calculateCost();
}
但重点是我不想重复代码,我宁愿添加到我覆盖的先前 toString() 方法中。请帮助或指导我(不确定我应该用谷歌搜索什么...)谢谢!
请注意,您是在 toString 方法中调用 calculateCost() 。因此 child 的 calculateCost() 被调用。您可以考虑使用 Child 的 toString 函数,如下所示。
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
在 Child
class 中被覆盖。因此,当从 Child
调用 super.toString()
时,super.toString()
中的 calculateCost()
将是 Child
的 calculateCost
.
您必须将 super.calculateCost()
显式放入 Child
class 才能调用 Parent
的 calculateCost
。
我认为为此您可以做的最好的事情是使用调试模式,这样您可以更好地理解它是如何工作的。阅读您的代码后,我了解您希望它如何 运行。
但是我觉得你实现@Override注解的方式有问题。
的意思@Override annotation is to implement a new method that had been literally overriding from the parent class.
在这种情况下,不会使用父项 class 的 public double calculateCost()
,因为您覆盖了子项 class 的计算成本。
希望我已经解释清楚了。但是在这种情况下,您需要做的是研究更多 @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 中的向上转换。
如果subclass 和parent class 都有一个方法.then 将执行subclass。如果不是,则将执行 parent class,尽管您调用 toString 方法包括 calculateCost
你的parentclass中的方法,但实际上会执行子class中的calculateCost方法。
您可以修改您的代码如下:
Parent Class
public class Parent{
public double calculateCostParent(){
return 77.77;
}
public String toString(){
return "Cost for Parent is: " + calculateCostParent();
}
}
Child Class
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
那你就可以避免parent和子class同时有相同的同名方法
您可以依赖于根据实际类型调用重写方法的最佳匹配。在这种情况下,您有一个 Child
的实例。因此,当您在重写或非重写实例方法中调用重写方法时,您将看到 Child
的实现。也就是说,
Parent p = new Child();
System.out.println(p);
会给出相同的结果。
我决定在我的父 class 中放置一个带有下划线前缀的私有函数,以便能够针对该特定函数并在我的父中仍然具有通用的 public 可覆盖函数实施。
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 中,每当我们调用一个对象的方法时,它属于 class 继承自其他 class ],JVM 检查该方法是否被 subclass 覆盖,因此尽管从 subclass 覆盖了 toString() 方法,计算 cost() 的调用解析为 subclass'版本。