Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-父类正在从子类调用方法?_Java_Inheritance_Overriding_Parent Child_Super - Fatal编程技术网

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()相同的内容,但只是稍微多了一点,所以我希望会有