2011-10-17 111 views
2

HEJ傢伙,C#繼承 - >的類層次結構

我理解在C#中繼承的過程中存在問題。我正在做功課,我想分享我想出的代碼。我也包括這個任務。

任務:

Work 1: 
    Develop a hierarchic structure of classes: shape, circle and cylinder: 

    Write the base class Shape which has two fields x and y coordinates The function 
    Display() returns a text string, which contains the point position. 

    The derived classes Circle and Cylinder inherit x , y coordinates and the method 
    Display() from base class Shape. You define the new necessary fields and methods 
    and you override the method Display() to return a text string with the coordinates, 
    the area and/or the volume. 

    The computing formulas are: 
    Circle area : p * r 2 
    Cylinder area: (2*p * r 2) + (2*p * r * h) 
    Cylinder volume: p * r 2 * h 

這是我的代碼有:

類Shape:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace A_Work_1 
{ 
    class Shape 
    { 
    public int xCoordinate = 0; 
    public int yCoordinate = 2; 

    public virtual void Display() 
    { 
     Console.WriteLine("The position of the point is: [{0};{1}].", xCoordinate, yCoordinate); 
    } 
} 
} 

類圈:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace A_Work_1 
{ 
class Circle : Shape 
{ 
    public override void Display() 
    { 
     double PI = Math.PI; 
     double radius = 2; 
     double circleArea = (PI * radius * radius); 
     Console.WriteLine("The area of the circle is: {0:F2}", circleArea); 
    } 

} 
} 

類氣缸:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace A_Work_1 
{ 
class Cylinder : Shape 
{ 
    public override void Display() 

    { 
     double PI = Math.PI; 
     double radius = 2; 
     double height = 5.5; 
     double cylinderArea = (2* PI * radius * radius) + (2 * PI * radius * height); 
     Console.WriteLine("The area of the cylinder is: {0:F2}", cylinderArea); 
     double cylinderVolume = (PI * radius * radius * height); 
     Console.WriteLine("The volume of the cylinder is: {0:F3}\n", cylinderVolume); 
    } 
} 
} 

而且主類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace A_Work_1 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine("A: Work 1\n"); 
     Shape position = new Shape(); 
     position.Display(); 

     Circle circleArea = new Circle(); 
     circleArea.Display(); 

     Cylinder cylinderArea = new Cylinder(); 
     cylinderArea.Display(); 

    } 
} 
} 

我想知道我在哪裏得到它錯了。繼承的想法對我來說有點難以理解。我如何改進這個練習來完成任務?

謝謝你的回答!五

編輯:

我已編輯的代碼,所以現在應該有適當的inherting。最後一個問題。我應該在哪裏放置代碼Console.WriteLine來獲取輸出?

類形狀:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace A_Work_1 
{ 
class Shape 
{ 
    public int xCoordinate = 0; 
    public int yCoordinate = 2; 

    public string Display() 
    { 
     string xCoordinateString = xCoordinate.ToString(); 
     string yCoordinateString = yCoordinate.ToString(); 
     return xCoordinateString + yCoordinateString; 
    } 
} 
} 

類圓圈:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace A_Work_1 
{ 
class Circle : Shape 
{ 
    public new string Display() 
    { 
     double PI = Math.PI; 
     double radius = 2; 
     double circleArea = (PI * radius * radius); 
     string circleAreaString = circleArea.ToString(); 
     return circleAreaString; 
    } 

} 
} 

類汽缸:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace A_Work_1 
{ 
class Cylinder : Circle 
{ 
    public string Display(double radius, double PI) 
    { 

     double height = 5.5; 
     double cylinderArea = (2* PI * radius * radius) + (2 * PI * radius * height); 
     string cylinderAreaString = cylinderArea.ToString(); 
     double cylinderVolume = (PI * radius * radius * height); 
     string cylinderVolumeString = cylinderVolume.ToString(); 
     return cylinderVolumeString + cylinderAreaString; 
    } 
} 
} 

Main類保持不變。 謝謝,五

最後編輯時間:

我修改了主類代碼,所以現在有Console.WriteLine這樣的代碼:

Shape position = new Shape(); 
Console.WriteLine(position.Display()); 

最後一個問題我有,是,當我運行應用程序我得到了圓區和圓柱區的相同編號。它看起來像Cylinder類中的Display方法使用Circle類的返回值。這怎麼可能?

+1

你說你はnt來知道你錯在哪裏。你認爲什麼是錯的?你沒有得到你期望的答案嗎? –

+2

創建圓柱體類時,應該考慮構圖,而不是重複計算圓的面積的代碼。圓柱可以表示爲圓形和高。然後使用圓的屬性來計算圓柱的體積和麪積 –

+0

@Rune,我也這麼認爲,但是指令告訴他'Cylinder'類只繼承了來自'Shape'的座標。可能它的措辭很糟糕。 –

回答

2

這是更好地半徑和高度移動到一流水平,是這樣的:

class Circle : Shape 
{ 
    public double radius = 2; 
    ... 

class Cylinder : Circle 
{ 
    public double height = 5.5; 
    ... 

而且你現在Display()並不好,這是編輯以前更好。它應該是無參數的,它應該是您的基本方法overrideDisplay()Shape

public virtual string Display() 
{ 
    return "[" + this.xCoordinate + ", " + this.yCoordinate + "]"; 
} 

Display()Circle

public override string Display() 
{ 
    return base.Display() + Environment.NewLine + 
     "Area = " + (Math.PI * this.radius * this.radius).ToString(); 
} 

Display()Cylinder

public override string Display() 
{ 
    return base.Display() + Environment.NewLine + 
     "Volume = " + (Math.PI * this.radius * this.radius * this.height).ToString(); 
} 

要寫入的效果,請使用:

Circle myCircle = new Circle(); 
Console.WriteLine(myCircle.Display()); 

Cylinder myCylinder = new Cylinder(); 
Console.WriteLine(myCylinder.Display()); 
+0

謝謝,這真是很好的解決方案!但是現在我的輸出是這樣的:從形狀輸出,從圓形輸出,再次從形狀輸出,再次從圓形輸出,從圓柱形輸出。我怎樣才能從每個只有一個? – Vojtech

+0

@Vojtech:對於所需的輸出,只需從方法中刪除'base.Display()+ Environment.NewLine'調用。 – Mentoliptus

+0

沒關係,現在我明白了,這是因爲調用Circle方法Display ..當我只打電話給Cylinder時,它的工作非常完美! – Vojtech

0

作業問題會要求您從顯示中返回一個文本字符串,而目前您將返回void。您需要將方法簽名更改爲返回字符串,然後調整您的調用代碼以使用(Console.WriteLine)顯示該字符串。

覆蓋形狀的每個類都應該定義它自己的私有屬性,例如circle應該有一個常量pi(因爲它永遠不會更改)和radius的屬性。這將允許您在圓上執行其他操作,而不必重新定義這些變量。

+6

爲什麼Math.Pi已經給出了一個常數? –

2

我認爲從現實生活的例子中可以更容易理解繼承。

可以說你有一個人,一個人有一個ID和一個名字。現在,讓我們說有一個警察,一個警察是從一個人繼承的,爲什麼?因爲每個警察首先是一個人(他有一個姓名和一個身份證),並且只有在那時你才能告訴他他是一個警察,如果他有其他EXTRA細節,如警察ID和武器。

在OOP中它是一樣的,一個繼承類(子類)與繼承類(父類)具有相同的屬性,但它有額外的東西,就像你的作業一樣,Circle類有更多獨特的東西,添加到形狀類。我們沒有在圓圈中重新編寫所有形狀的東西,而是繼承Shape類並在Circle類中添加額外的信息。

這讓我們更容易瞭解其他程序員,讓他們瞭解軟件對象是什麼,以及它們如何在自己之間進行連接,並用於模擬「真實世界」中的對象(如果您有例如信息系統管理工作的力量,你可以有一個父類中的「工人」和子類監事」的,因爲每一個監督員首先是工人)。

希望它能幫助。

和特定的功課:

我會d o在你的具體作業中正在改變繼承,所以圓是從形狀繼承而圓柱體是從圓繼承。因爲每個Cylinder也是一個圓圈,具有額外的屬性。

+0

非常感謝你的真實生活的例子。現在對我來說更清楚了!我改變了Cylinder類,所以它繼承了Circle的屬性,現在它就像一個魅力! – Vojtech

+0

不客氣。 –

+0

一個圓柱不是一個圓。圓是二維物體,圓柱體是具有圓形底座的三維物體。這不是繼承的候選人,但組成 –

1

形狀是繼承的經典教科書示例。不幸的是,這也是一個很難正確的案例。

繼承的基本規則是你可以建立一個繼承的關係。

你可以說一個矩形是一個形狀,你也可以說一個正方形是一個形狀。在數學上,你也可以說每個正方形都是一個矩形。但是,如果您從矩形派生出方形,則必須與Lisskov進行聊天。 A square is modellingwise not a rectangle

就拿這個例子中(可能會出現在鏈接到文章中給出的問題進一步解釋)

public class Rectangle : Shape{ 
    public virtual int Width{get;set} 
    public virtual int Height{get;set} 
} 

public class Square : Rectangle{ 
    public override int Width{get{return Height;} set{Height = value;}} 
} 

的在你的代碼中有

rect.Height = 10; 
rect.Width = 5; 

第二行的一些地方可能更改高度是因爲將矩形替換爲矩形的問題。

圓形和圓柱體也是如此。有多少個半徑爲0.2英寸的圓可以在4平方英寸的面積上畫一張紙?有多少個圓柱?我沒有計算出前者,但後者的答案是沒有。它是三維形狀並且不能在二維空間中繪製,你怎麼可以構造一個基於圓的圓柱體和圓柱體高度的知識,這種關係是用構圖建模的

在這個特殊情況下,你可以做

abstract class Shape{ 
    public abstract double Area{get;} 
} 

class Cylinder : Shape{ 
private Circle baseCircle; 
private double height; 

public override double Area{ 
get{//use height and baseCircle for the calculation left. 
    //Actual code left out because it's homework} 
} 

和同樣適用於批量使用高度和baseCircle計算volumen的區域。

+0

謝謝澄清!你的意思是'覆蓋區域' - >它應該是一個變量嗎?還是另一個班? – Vojtech

+0

@Vojtech它覆蓋了具有相同名稱形狀的抽象屬性(我原來有點馬虎,現在糾正了) –

+0

帶有getter和setter的公共屬性以及只讀的'Area'屬性是一個更好的解決方案,但這與Vojtech提出的要求相差甚遠。我們爲他的任務提供了更簡單的解決方案。 – Mentoliptus