Java - 父类是从子类调用方法吗?

时间:2017-07-12 02:53:25

标签: java inheritance override 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 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());
    }
}

在我看来,Child类中的toString()应该从Parent类调用toString()(因此,来自Parent类的calculateCost())然后使用来自Child的calculateCost()添加它。我猜测super.toString()中的super不适用于它包含的calculateCost()。

另外,我知道我可以通过在Child类中编写toString()来解决它:

    @Override
    public String toString(){
        return "Cost for Parent is: " + super.calculateCost() + "\nCost for Child is: " + calculateCost();
    }

但关键是我不想重复代码,而是我宁愿添加到我覆盖的前一个toString()方法。请帮忙或指导我(不知道我应该谷歌搜索...)谢谢!

8 个答案:

答案 0 :(得分:0)

请注意,您在toString方法中调用calculateCost()。因此,孩子的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();
}
}

答案 1 :(得分:0)

calculateCostChild类中被覆盖。因此,当super.toString()调用Child时,calculateCost()中的super.toString()将成为Child的{​​{1}}。

您必须在calculateCost课程中明确地super.calculateCost()拨打Child的{​​{1}}。

答案 2 :(得分:0)

这是java中的upcasting 如果子类和父类都有一个方法。那么将执行子类。如果没有,那么将执行父类,尽管您调用 toString 方法,包括 calculateCost

在您的父类中的方法,但实际上子类中的 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

然后你可以避免父类和子类同时具有相同名称的相同方法。

答案 3 :(得分:0)

您可以根据实际类型依赖于被覆盖方法的最佳匹配。在这种情况下,您有一个Child的实例。因此,当您在重写或未重写的实例方法中调用重写方法时,您将看到Child的实现。换句话说,

Parent p = new Child();
System.out.println(p);

会得到相同的结果。

答案 4 :(得分:0)

在这种情况下,我决定在我的父类中放置一个带下划线的私有函数,以便能够针对该特定函数,并且在我的父实现中仍具有通用的公共可重写函数。

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());
    }
}

答案 5 :(得分:0)

我认为这是 JVM 的行为,因为在 Java 中,每当我们调用对象上的方法时,该对象属于从其他类继承的类,JVM 会检查该方法是否被覆盖子类,因此尽管覆盖了子类的 toString() 方法,但对计算 cost() 的调用解析为子类的版本。

答案 6 :(得分:-1)

我认为你可以做的最好的事情是使用调试模式,这样你就可以更好地理解它是如何工作的。阅读完代码后,我了解您希望它如何运行。

但我认为你实现 @Override Annotation的方式存在问题。

的含义
  

@Override注释是为了实现一个新的方法   从父类中完全覆盖。

在这种情况下,由于您覆盖了Child类的calculatecost,因此不会使用Parent类的public double calculateCost()

我希望我已经解释得很好。但在这种情况下,您需要做的是研究更多的@Override,并了解它是如何工作的。

答案 7 :(得分:-1)

您可以做的最好的事情是创建父对象和子对象。从子的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