2011-06-30 68 views
0

我有以下練習: 定義一個名爲circle的類,它接受類型爲point的對象,並計算它們與圓心的距離。如果該點在圈外應該發送異常通知。例外 - 基本練習

這是我的代碼:

class Point 
{ 
    protected int x,y; 
    public Point(int x,int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 
} 
class Circle : Point 
{ 
    public Circle(Point p,int radius):base(3,5) 
    { 

    } 

} 
class Program 
{ 
    static void Main(string[] args) 
    { 

    } 
} 

我不知道我必須在圈內類的事,我怎麼能知道,如果點是在圈內還是不是? 謝謝大家。

+1

這功課嗎? – Aidan

+4

我不明白你爲什麼使Circle *派生自*點在這裏......它意味着有一種方法*接受*類型Point的值,據我所見.... –

+0

這不是,我正在度假。我正在努力學習這一點。 –

回答

7

定義接受型點的對象一類命名爲圓形,並計算它們與圓心的距離。如果該點在圈外應該發送異常通知。

繼承與組成:首先,它似乎是錯誤的,你的Circle類從Point派生,只因爲你需要一個xy座標對你的圈子了。請記住,繼承通常模擬「是 - 一個」關係。但圈子不是要點。相反,可以說它們可以通過一個點(中心)和一個半徑來定義。因此,這將是更符合邏輯可用的組合物(「有」的關係):

class Circle 
{ 
    Point center; 
    double radius; 
} 

當使用異常(以及何時不):第二,我希望誰給你的練習沒」 t實際上意味着throw是一個例外,因爲您的距離計算方法得到了位於圓圈外的Point。我會認爲這種使用例外是無效的。例外情況應該適用於某些情況下您的代碼無法正確處理的情況。但是,計算兩點之間的距離決不會失敗(除非也許像溢出或下溢怪異浮點問題):

double DistanceFromCentreTo(Point p) 
{ 
    // See e.g. http://en.wikipedia.org/wiki/Pythagorean_theorem: 
    return Math.Sqrt((center.x - p.x) * (center.x - p.x) + 
        (center.y - p.y) * (center.y - p.y)); 
} 

如果突然這樣的方法拋出一個異常,你的代碼的很多用戶可能會考慮這個unlogical。爲什麼這種方法超出其名稱所建議的範圍,只因距離大於radius而拋出異常?

這將是更明智IMO引入第二種方法:

bool LiesWithinCircle(Point p) 
{ 
    return DistanceFromCentreTo(p) <= radius; 
} 

現在你有兩個方法,無論怎麼做多數人的期待,不亂扔意外的異常,並仍然提供所有功能,你很可能需要。


PS:許多天以後讀我的回答,突然讓我覺得,這將是更好的還是定義在Point類上面所示的兩種方法來代替,例如:

double DistanceToCenterOf(this Point p, Circle c) { … } 
bool LiesWithin  (this Point p, Circle c) { … } 

...這導致了更易於理解的代碼;例如somePoint.LiesWithin(someCircle)而不是someCircle.LiesWithinCircle(somePoint)

+0

@stakx非常感謝你的很好的解釋,我現在會嘗試做這個練習,順便說一句,我正在寫一本書。 –

+0

@stakx我試過這樣做,現在是代碼:http://pastebin.com/5mbHaxZ3我的問題是,如果我只得到Point p而不是中心點,那麼函數calc距離?謝謝。 –

+0

@很好,首先,你的當前代碼中有一個錯字。您需要執行'Math.Sqrt(... + ...)',而不是'Math.Sqrt(... - ...)'。然後,回答你的問題,你是對的,要計算距離,你需要兩點。你有這些:'p'(距離...'方法的一個參數)和'center'(你的'Circle'類的一個字段)。但是當然你需要初始化'中心',例如通過將中心點傳遞給Circle的構造函數:class Circle {... public Circle(Point center,double radius){this.center = center; this.radius =半徑; } ...' – stakx

2

我怎麼知道點是否在 圈?點和中心之間

  1. 計算距離。
  2. 如果它大於半徑,那麼它在外面。
+0

感謝您的回答,但您有什麼想法,我需要在圓形構造函數中做什麼? –

1

這會告訴你,如果你是在圓或不:

class Point 
{ 
    protected int x,y; 
    public Point(int x,int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public int X { get { return x; } } 
    public int Y { get { return y; } } 
} 

在圈的構造函數:

public Circle(Point p,int radius):base(3,5) 
{ 

    if (Math.Sqrt(Math.Pow(p.X - this.X, 2.0) + Math.Pow(p.Y - this.Y, 2.0)) > radius) 
     throw new ArgumentException("This point is outside the circle"); 
} 
+0

這假定你已經從Point派生出來,這樣圓的中心就在這個點上。正如Jon Skeet指出的那樣,這是糟糕的形式。繼承模型是一種關係,而一個圓並不是一個點。 – Aidan

+0

這段代碼好嗎? –

+0

http://pastebin.com/zdVu2iu3 –

1

應該是這樣的,假設你只問異常和已經知道計算距離所涉及的邏輯:

class Circle 
{ 
    public Circle(Point p,int radius) 
    { 
     //code to construct the circle here.. 
    } 

    public double DistanceFromCenter(Point p) 
    { 
     if (p is outside circle) 
      throw new Exception("Point " + p + " is outside the circle"); 
     //calculate the distance and return it... 
    } 
} 
+0

我將添加到您的(好)答案中的兩件事:**(1)**'DistanceFromCenter'應該可能返回一個浮點數,而不是'int'。 **(2)**應該補充說的是,在這種情況下使用例外情況可能被認爲是錯位的。即使距圓心遠離圓的半徑,「DistanceFromCenter」始終可以返回有效結果,並且異常可能是意外的。增加另一種方法'bool IsInsideCircle(Point p)'似乎更爲明智。例外情況應該用於發生意外的事情,你的代碼無法處理。 – stakx

+0

我不認爲DistanceFromCenter應該返回int。更像是我的雙倍。 –

+0

@stakx謝謝,好點..也許甚至值得單獨的答案,因爲OP是非常模糊的第一位。 :) –

0

圓圈上的原點的半徑R是x^2+y^2=R^2點在圓圈如果x^2 + Y^2 < = R^2