簡體   English   中英

Java - 父類正在從子類調用方法?

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

在我看來,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() 方法中。 請幫助或指導我(不知道我應該在谷歌上搜索什么......)謝謝!

請注意,您正在 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();
}
}

Child類中覆蓋了calculateCost 因此,當super.toString()從所謂的Child中, calculateCost()super.toString()將是ChildcalculateCost

您必須將super.calculateCost()明確地放在Child類中才能調用ParentcalculateCost

這是在java中向上轉換。
如果子類和父類都有方法 .then 將執行子類。 如果沒有,則將執行父類,盡管您調用了包括計算成本的toString方法

父類中的方法,但實際上將執行子類中的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的實例。 因此,當您在重寫或非重寫實例方法中調用重寫方法時,您將看到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() 方法,但對計算 cost() 的調用解析為子類的版本。

我認為為此你能做的最好的事情就是使用調試模式,這樣你就可以更好地了解它是如何工作的。 閱讀您的代碼后,我了解您希望它如何運行。

但我認為你如何實現@Override Annotation存在問題 的意義

@Override 注解是為了實現一個新的方法,這個方法實際上是從父類重寫的。

在這種情況下,將不會使用 Parent 類的public double calculateCost() ,因為您覆蓋了 Child 類的 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM