2015-09-27 87 views
0

我在java中有繼承鏈的問題 我有一個接口幾何,一個類Circle實現幾何,一個類Cylinder擴展Circle。因爲Circle沒有Volume,我將它返回到0.當Cylinder擴展Circle時,Volume返回V = PI * Radius * Radius * Height 但是我創建Cylinder的實例是cy,當它調用getVolume()時,它返回0圈。它如何調用getVolume()本身,而不是Circle? 謝謝。這是我的代碼:如何防止java中的繼承鏈

public interface Geometry { 

    public double getArea(); 

    public double getVolume(); 
} 

class Circle implements Geometry { 

    public double R; 

    public double getArea() { 
     return Math.pow(R, 2) * Math.PI; 
    } 

    public double getVolume() { 
     return 0; // because not volume of Circle 
    } 
} 

class Cylinder extends Circle { 

    public double Height; 

    //lateral area of Cylinder 
    public double getArea() { 
     double s = super.getArea(); 
     return 2 * s + 2 * Math.PI * super.R * this.Height; 
    } 

    public double getVolume() { 
     return Math.PI * Math.pow(R, 2) * Height; 
    } 
} 

public class Main { 

    public static void main(String[] args) { 
     Cylinder cy = new Cylinder(); 
     cy.R = 1; 
     System.out.println(cy.getArea()); // 6.28 
     System.out.println(cy.getVolume()); // 0 Wrong!!! 
    } 
} 
+1

您需要進一步的抽象。聽起來像一個[基本Liskov解僱問題](https://en.wikipedia.org/wiki/Liskov_substitution_principle#A_typical_violation):一個正方形是一個矩形,但是你將無法用正方形替換應用程序中的所有矩形。也許你應該在'Geometry'和'Cylinder'之間有一個支持音量的接口。 –

回答

2

它沒有返回圓的getVolume(),但由於您沒有設置高度音量來了零return Math.PI * Math.pow(R, 2) * Height; 可以證實這一點通過把一個的System.out.println該方法中的聲明。

但無論如何這個層次結構是不正確的,你不應該用圓形擴展圓柱體,因爲圓柱體不是圓形。繼承是用來從一個通用的類型,如狗的動物,圓柱體和圓圈在這個意義上說是不相關的,所以你錯了繼承

0

我認爲你的問題不是Circle的getVolume調用。所調用的方法是Cylinder's,但Height屬性爲0,因此返回值爲0。

你需要你的汽缸實例(CY)的高度屬性設置爲:

cy.Height = 3.00; 
0

繼承是由初級程序員過度使用

你的想法,在這裏使用繼承打破了很多很多的規則OOP。其中最基本的是,一個氣缸不是一個循環。

在OOP中還有其他代碼重用的機制,但初學者往往傾向於繼承,因爲它顯然是FOR的重用。

封裝和組成

在這種情況下,我會鼓勵你用的組合物,這是封裝的結果。

在這種情況下,我會鼓勵你做一個名爲Prism類,它包含兩個屬性,HeightFace,其中第二個是,你把你的Circle