整個專案檔連結
https://drive.google.com/file/d/0B9vj2TjBHPutam1SeGxCZ0pvUE0/edit?usp=sharing 換行
Const.cs
namespace HW8___多邊體計算視窗程式3
{
static class GeoConst
{
public static readonly double Pi = 3.14159;
}
static class MetrialConst
{
public static readonly double Density_Wood = 0.8;
public static readonly double Density_Ice = 0.9;
public static readonly double Density_Al = 2.7;
public static readonly double Density_Fe = 7.87;
public static readonly double Density_Pb = 11.3;
}
}
IRollable.cs
namespace HW8___多邊體計算視窗程式3
{
interface IRollable
{
double RollDistance();
}
}
Shape.cs
namespace HW8___多邊體計算視窗程式3
{
abstract class Shape
{//此為抽象類別,不可以實體化,因為形狀不是任何一種形狀
private static int _count = 0;
public static int Count { get { return _count; } }
private double _density = 0;
public double Density
{
get { return _density; }
set { _density = value; }
}
static private int _serialNumber; //報名流水號(目前最後的,只增不減)
public readonly int SerialNumber; //報名流水號(每個物件自己的,new 後不可改)
//建構子
public Shape()
{
_count++;
SerialNumber = _serialNumber++;
}
//解構子
~Shape()
{
_count--;
}
public double Weight()
{//重量=體積*密度, 不須另外宣告變數存放
return Bulk() * _density;
}
public abstract double Bulk();//體積演算法每種形狀都不同, 留給衍生類實作
}
}
Ball.cs
namespace HW8___多邊體計算視窗程式3
{
class Ball : Shape, IRollable
{
private static int _count = 0;
new public static int Count { get { return _count; } }
//長度參數
private double _radius = 0;
//建構子
public Ball(double radius, double density)
{
this.Density = density;
this._radius = radius;
_count++;
}
//解構子
~Ball()
{
_count--;
}
public override double Bulk()
{
return (4.0 / 3.0) * GeoConst.Pi * _radius * _radius * _radius;
}
public double RollDistance()
{//prototype at Interface
return _radius * _radius;
}
}
}
Cube.cs
namespace HW8___多邊體計算視窗程式3
{
class Cube : Shape
{
private static int _count = 0;
new public static int Count { get { return _count; } }
//長度參數
private double _side = 0;
//建構子
public Cube(double side, double density)
{
this.Density = density;
this._side = side;
_count++;
}
//解構子
~Cube()
{
_count--;
}
public override double Bulk()
{
return _side*_side*_side;
}
}
}
Cylinder.cs
namespace HW8___多邊體計算視窗程式3
{
class Cylinder : Shape,IRollable
{
private static int _count = 0;
new public static int Count { get { return _count; } }
//長度參數
private double _radius = 0;
private double _height = 0;
//建構子
public Cylinder(double radius, double height, double density)
{
this.Density = density;
this._radius = radius;
this._height = height;
_count++;
}
//解構子
~Cylinder()
{
_count--;
}
public override double Bulk()
{
return GeoConst.Pi * _radius * _radius * _height;
}
public double RollDistance()
{//prototype at Interface
return _radius * 5;
}
}
}
Pyramid.cs
namespace HW8___多邊體計算視窗程式3
{
class Pyramid : Shape
{
private static int _count = 0;
new public static int Count { get { return _count; } }
//長度參數
private double _side = 0;
private double _height = 0;
//建構子
public Pyramid(double side, double height, double density)
{
this.Density = density;
this._side = side;
this._height = height;
_count++;
}
//解構子
~Pyramid()
{
_count--;
}
public override double Bulk()
{
double _dSide = _side/1000;
double _dHeight = _height/1000;
double _tempBulk=0;
for (int i=0; i<1000 ; i++ )
{//從最底下的那片體積往上加,邊長一直縮小
double _currentSide = _side - (i * _dSide * 0.5); //0.5 使 side 修正到斜邊中點
_tempBulk += _currentSide * _currentSide * _dHeight;
}
return _tempBulk;
}
}
}
Form1.cs
namespace HW8___多邊體計算視窗程式3
{
public partial class Form1 : Form
{
private List ListShape = new List();
public Form1()
{
InitializeComponent();
}
private double DensityTable(string material)
{
if (material == "木材") return MetrialConst.Density_Wood;
if (material == "冰") return MetrialConst.Density_Ice;
if (material == "鋁") return MetrialConst.Density_Al;
if (material == "鐵") return MetrialConst.Density_Fe;
if (material == "鉛") return MetrialConst.Density_Pb;
return -9999;
}
private void btnAddNewShape_Click(object sender, EventArgs e)
{
///================ 使用者輸入檢查 開始 ================
bool _checkPass = false; //標記使用者是否通過防呆檢查
string _forget = ""; //存放使用者忘記輸入的項目
int _dummyInt; //供int.TryParse()檢查用
double _dummyDouble; //供double.TryParse()檢查用
//逐條審查,不可用switch case
if (null == cbBox_Material.SelectedItem)_forget += " 材質";
if (null == cbBox_Shape.SelectedItem) _forget += " 形狀";
if (!int.TryParse(txtBox_AddNewShapeNum.Text, out _dummyInt)) _forget += " 數量";
if (!double.TryParse(txtBox_ShapeParameter1.Text, out _dummyDouble)) _forget += " 第1個形狀參數";
if ((cbBox_Shape.SelectedItem.ToString() == "圓柱體") || (cbBox_Shape.SelectedItem.ToString() == "金字塔"))
{
if ("" == txtBox_ShapeParameter2.Text) _forget += " 第2個形狀參數";
}
//拋出檢查結果. 若無錯誤就Pass
if ("" != _forget)
MessageBox.Show("你忘記輸入" + _forget + " !\a");
else
_checkPass = true;//無錯誤
//================ 使用者輸入檢查 結束 ================
//若是沒有通過防呆檢查,以下這個迴圈會被by pass
for(int i=0;_checkPass && i小於(轉到32bit整數(文字盒子_AddNewShapeNum.Text));i++)
{//原本程式碼貼上來網頁會錯誤,後面的程式碼都會亂掉,所以只好這樣寫
double _localDensity = DensityTable(cbBox_Material.Text);//取得選單所選之密度數值
switch (cbBox_Shape.SelectedItem.ToString())
{
case "球":
{
double _tempRadius = Convert.ToDouble(txtBox_ShapeParameter1.Text);
ListShape.Add(new Ball(_tempRadius, _localDensity));
txtBox_ShapeList1.AppendText("Ball \t"
+ "半徑=" + Convert.ToString(_tempRadius) + " ");
}
break;
case "正方體":
{
double _tempSide = Convert.ToDouble(txtBox_ShapeParameter1.Text);
ListShape.Add(new Cube(Convert.ToDouble(txtBox_ShapeParameter1.Text), _localDensity));
txtBox_ShapeList1.AppendText("Cube \t"
+ "邊長=" + Convert.ToString(_tempSide) + " ");
}
break;
case "圓柱體":
{
double _tempRadius = Convert.ToDouble(txtBox_ShapeParameter1.Text);
double _tempHeight = Convert.ToDouble(txtBox_ShapeParameter2.Text);
ListShape.Add(new Cylinder(_tempRadius, _tempHeight, _localDensity));
txtBox_ShapeList1.AppendText("Cylinder \t"
+ "半徑=" + Convert.ToString(_tempRadius) + " "
+ "高度=" + Convert.ToString(_tempHeight) + " ");
}
break;
case "金字塔":
{
double _tempSide = Convert.ToDouble(txtBox_ShapeParameter1.Text);
double _tempHeight = Convert.ToDouble(txtBox_ShapeParameter2.Text);
ListShape.Add(new Pyramid(_tempSide, _tempHeight, _localDensity));
txtBox_ShapeList1.AppendText("Pyramid \t"
+ "邊長=" + Convert.ToString(_tempSide) + " "
+ "高度=" + Convert.ToString(_tempHeight) + " ");
}
break;
}
txtBox_ShapeList1.AppendText("編號=" + ListShape.Last().SerialNumber + "\n");
ReflashNumberOfEachClass();
}
}
private void cbBox_Shape_SelectedIndexChanged(object sender, EventArgs e)
{//顯示介面控制, 當使用者改變 形狀 時, 動態更動UI
switch (cbBox_Shape.SelectedItem.ToString())
{
case "球":
{
labelParameter1.Text = "直徑"; txtBox_ShapeParameter1.Visible = true;
labelParameter2.Text = ""; txtBox_ShapeParameter2.Visible = false;
}
break;
case "正方體":
{
labelParameter1.Text = "邊長"; txtBox_ShapeParameter1.Visible = true;
labelParameter2.Text = ""; txtBox_ShapeParameter2.Visible = false;
}
break;
case "圓柱體":
{
labelParameter1.Text = "直徑"; txtBox_ShapeParameter1.Visible = true;
labelParameter2.Text = "高"; txtBox_ShapeParameter2.Visible = true;
}
break;
case "金字塔":
{
labelParameter1.Text = "邊長"; txtBox_ShapeParameter1.Visible = true;
labelParameter2.Text = "高"; txtBox_ShapeParameter2.Visible = true;
}
break;
}
}
private void btnCalcShapeParameter_Click(object sender, EventArgs e)
{
if (null == cbBox_SortAlgorithms.SelectedItem)
{//使用者輸入檢查
MessageBox.Show("未選擇排序法! 依預設順序列出");
}
else
{
switch (cbBox_SortAlgorithms.SelectedItem.ToString())
{
case "順序":ListShape.Sort(Sort.BySerialNumber);break;
case "形狀":ListShape.Sort(Sort.ByShape);break;
case "材質":ListShape.Sort(Sort.ByMetrial);break;
case "體積":ListShape.Sort(Sort.ByBulk);break;
case "重量":ListShape.Sort(Sort.ByWeight);break;
}
}
txtBox_ShapeList2.Clear();//清除畫面
for (int i = 0; i < ListShape.Count ; i++)
{//開始依序列出
txtBox_ShapeList2.AppendText( ListShape[i].GetType().Name + "\t "
+ "密度:" + ListShape[i].Density.ToString("f2") + "\t "
+ "體積:" + ListShape[i].Bulk().ToString("f2") + "\t "
+ "重量:" + ListShape[i].Weight().ToString("f2") + "\t "
+ "編號=" + ListShape[i].SerialNumber
+ "\n");
}
}
private void btnCalcRollDistance_Click(object sender, EventArgs e)
{
txtBox_ShapeListForRollDistance.Clear();//清除畫面
for (int i = 0; i < ListShape.Count; i++)//檢查每一個由Shape refenece 管理的物件
{
//取得 ListShape[i] 的類別資訊
bool _isIRollable = ListShape[i] is IRollable;
if (_isIRollable)
{//如果是可以滾動的Shape衍生類,就進來
IRollable _tempRollable = ListShape[i] as IRollable; //向下轉型
txtBox_ShapeListForRollDistance.AppendText(
_tempRollable.GetType().Name + "\t " +
"滾動距離:" + _tempRollable.RollDistance().ToString("f2") + "\t " +
"\n");
}
}//迴圈結束
}
private void ReflashNumberOfEachClass()
{
label_NumberOfEachClass.Text = "球體=" + Ball.Count + " "
+ "正方體=" + Cube.Count + " "
+ "圓柱體=" + Cylinder.Count + " "
+ "金字塔=" + Pyramid.Count + " "
;
}
private void btnDeleteSomeOneShape_Click(object sender, EventArgs e)
{
bool _find = false;
for (int i = 0; i < ListShape.Count; i++)
{
if (ListShape[i].SerialNumber == Convert.ToInt32(txtBox_DeleteSomeOneShapeSerialNum.Text))
{
//強迫回收
ListShape[i] = null;
GC.Collect();
GC.WaitForPendingFinalizers();
//清除空位置
ListShape.RemoveAt(i);
_find = true;
break;
}
}
ReflashNumberOfEachClass();
if (!_find)
MessageBox.Show("這個編號的物件不存在!\a");
}
}
}
[第六組]
回覆刪除第一次看到用在常數那邊的static readonly, google後找到這篇文章.
http://www.dotblogs.com.tw/yc421206/archive/2011/06/06/27232.aspx
雖然之前課堂上有人提過const和static作為常數修飾詞的差別,不過後來覺得只是小事就沒去查了... 你們很用心,也提醒了我們這個小細節,感謝!
namespace的部分一樣還是希望你們注意一下,不要用中文命名.
Pyramid的體積公式之前有同學提過,建議你改一下,不用再用for迴圈跑XD
form1.cs的DensityTable,裡面的5個if應該可以改用switch case代替.
form1.cs:49~50行你可以把.cs檔上傳上來,我會幫你處理.
form1.cs:排序的部分,自定義比較器是寫在Sort.cs嗎?是的話記得貼上來給大家看一下.
最後,也要記得提供執行檔讓大家一起測試.
作者已經移除這則留言。
刪除林高遠:你是誰?
刪除