public abstract class PartBase : Space { #region 基本属性 /// <summary> /// 是否复合板 /// </summary> public bool IsCladPart { get; set; } /// <summary> /// 基层密度(kg/L) /// </summary> public double BaseDensity { get; set; } /// <summary> /// 复层密度(kg/L) /// </summary> public double CladDensity { get; set; } /// <summary> /// 基层材料 /// </summary> public string BaseMaterial { get; set; } /// <summary> /// 复层材料 /// </summary> public string CladMaterial { get; set; } /// <summary> /// 零件类型 /// </summary> public PartType PartType { get; set; } #endregion 基本属性 #region 控件属性 public TextBox TbBaseDensity { get; set; } public TextBox TbCladDensity { get; set; } public TextBox TbBaseMaterial { get; set; } public TextBox TbCladMaterial { get; set; } public CheckBox CbxIsCladPart { get; set; } #endregion 控件属性 #region 控件事件,由于是抽象类,需要在继承类中实现其事件 public virtual void TbDensity_Validating(object sender, CancelEventArgs e) { "未实现【密度】的虚方法!".showAlert(); } public virtual void TbCladMaterial_Validating(object sender, System.ComponentModel.CancelEventArgs e) { "未实现【复层材料】的虚方法!".showAlert(); } public virtual void TbBaseMaterial_Validating(object sender, System.ComponentModel.CancelEventArgs e) { "未实现【基层材料】的虚方法!".showAlert(); } public virtual void CbxIsCladPlate_CheckedChanged(object sender, EventArgs e) { "未实现【是否复合板】的虚方法!".showAlert(); } #endregion 控件事件,由于是抽象类,需要在继承类中实现其事件 public PartBase() { } /// <summary> /// 继承腔体类中的属性值 /// 并且设置下一级类中的属性值 /// </summary> /// <param name="v"></param> /// <param name="s"></param> public PartBase(Vessel v, Space s) : base(v, s) { } }
继承抽象类的下一级普通类需要:
1.重写抽象类A中的虚事件。
2.赋值A中属性便于向下传递。
3.本类B中的属性值需要通过类实例b传递到下一级属性中。
4.普通类B必须要有一个代表类实例的属性b,便于在本类中进行值的储存。比如,验证TextBox中用户输入的数值,如果值可以接受的话可以存储在b属性中。
5.在下级类实例化构造过程中传值给此实例属性b。
public class ShellBase : PartBase { #region 公用属性 /// <summary> /// 壳体名义厚度 /// </summary> protected string zShellTn; /// <summary> /// 壳体名义厚度 /// </summary> public string ShellTn { get { return zShellTn; } set { zShellTn = value; if (IsCladPart) { if (value.Contains("+")) { TnBase = double.Parse(value.Split('+')[0]); TnClad = double.Parse(value.Split('+')[1]); Tn = TnBase + TnClad; } else { } } else if (!string.IsNullOrEmpty(value)) { if (value.Contains("+")) { } else { double tn = 0; double.TryParse(value, out tn); Tn = tn; } } } } /// <summary> /// 壳体公称厚度 /// </summary> public double Tn { get; set; } /// <summary> /// 是否为外径基准 /// </summary> public bool IsBasedOnOD { get; set; } /// <summary> /// 壳体公称直径 /// </summary> public double ShellDn { get; set; } /// <summary> /// 基层厚度 /// </summary> public double TnBase { get; set; } /// <summary> /// 复层板厚 /// </summary> public double TnClad { get; set; } /// <summary> /// 当前类的一个实例,用于记录验证时的值,重要,它是一个传值桥梁 /// </summary> public ShellBase Shell { get; set; } #endregion 公用属性 #region 几何属性 /// <summary> /// 体积 /// </summary> public double Volume { get; set; } /// <summary> /// 内表面积 /// </summary> public double InnerArea { get; set; } /// <summary> /// 外表面积 /// </summary> public double OuterArea { get; set; } /// <summary> /// 质量 /// </summary> public double Mass { get; set; } #endregion 几何属性 #region 控件属性 public CheckBox CbxIsBasedOnOD { get; set; } public TextBox TbShellDn { get; set; } public TextBox TbShellTn { get; set; } public Label LblVolume { get; set; } public Label LblMass { get; set; } public Label LblInnerArea { get; set; } public Label LblOutterArea { get; set; } #endregion 控件属性 #region 控件事件 private void TbShellTn_Validating(object sender, System.ComponentModel.CancelEventArgs e) { if (TbShellTn.Text == "") { ErrShow.Clear(); return; } if (IsCladPart) { List<double> lst = TbShellTn.getCladPlateThickness(); Shell.ShellTn = TbShellTn.Text; if (lst.Count > 1) { Shell.TnBase = lst[0]; Shell.TnClad = lst[1]; Shell.Tn = TnBase + TnClad; ErrShow.Clear(); } else { ErrShow.SetError(TbShellTn, "请按复合板的厚度【50+4.5】的格式填写!"); e.Cancel = true; } } else { Shell.TnBase = TbShellTn.getNumber(); Shell.Tn = TnBase; Shell.ShellTn = TbShellTn.Text; ErrShow.Clear(); } } private void TbShellDn_Validating(object sender, System.ComponentModel.CancelEventArgs e) { if (TbShellDn.Text == "") { ErrShow.Clear(); return; } double dn = 0; double.TryParse(TbShellDn.Text, out dn); if (dn > 20) { Shell.ShellDn = dn; ErrShow.Clear(); } else { ErrShow.SetError(TbShellDn, "输入的数据有误!"); e.Cancel = true; } } private void CbxIsBasedOnOD_CheckedChanged(object sender, EventArgs e) { Shell.IsBasedOnOD = CbxIsBasedOnOD.Checked; } /// <summary> /// 重写抽象类中的方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public override void CbxIsCladPlate_CheckedChanged(object sender, EventArgs e) { Shell.IsCladPart = CbxIsCladPart.Checked; } public override void TbDensity_Validating(object sender, CancelEventArgs e) { TextBox tb = (TextBox)sender; if (tb.Text == "") { if (tb == TbBaseDensity) { Shell.BaseDensity = 0; } else { Shell.CladDensity = 0; } ErrShow.Clear(); return; } double midu = 0; double.TryParse(tb.Text, out midu); if (midu > 1 && midu < 30) { if (tb == TbBaseDensity) { Shell.BaseDensity = midu; } else { Shell.CladDensity = midu; } ErrShow.Clear(); } else { ErrShow.SetError(tb, "密度输入有问题!"); e.Cancel = true; } } public override void TbCladMaterial_Validating(object sender, System.ComponentModel.CancelEventArgs e) { Shell.CladMaterial = TbCladMaterial.Text; } public override void TbBaseMaterial_Validating(object sender, System.ComponentModel.CancelEventArgs e) { Shell.BaseMaterial = TbBaseMaterial.Text; } #endregion 控件事件 public ShellBase() { } public ShellBase(Vessel V, Space S) : base(V, S) { } /// <summary> /// 继承腔体类中的属性值 /// 并且设置下一级类中的属性值 /// </summary> /// <param name="V"></param> /// <param name="S"></param> public ShellBase(Vessel V, Space S, ShellBase SB) : base(V, S) { //传值 Shell = SB; #region 控件赋值 //PartBase if (SB.CbxIsCladPart != null) { CbxIsCladPart = SB.CbxIsCladPart; } if (SB.TbBaseDensity != null) { TbBaseDensity = SB.TbBaseDensity; } if (SB.TbCladDensity != null) { TbCladDensity = SB.TbCladDensity; } if (SB.TbBaseMaterial != null) { TbBaseMaterial = SB.TbBaseMaterial; } if (SB.TbCladMaterial != null) { TbCladMaterial = SB.TbCladMaterial; } //ShellBase if (SB.CbxIsBasedOnOD != null) { CbxIsBasedOnOD = SB.CbxIsBasedOnOD; } if (SB.TbShellDn != null) { TbShellDn = SB.TbShellDn; } if (SB.TbShellTn != null) { TbShellTn = SB.TbShellTn; } #endregion 控件赋值 #region 属性传值 IsBasedOnOD = SB.IsBasedOnOD; ShellDn = SB.ShellDn; Tn = SB.Tn; ShellTn = SB.ShellTn; TnBase = SB.TnBase; TnClad = SB.TnClad; #endregion 属性传值 #region 通过将SB赋值给本类中属性Shell,用Shell来接收控件验证时得到的参数值,然后传值到下一个继承者 //赋值是从抽象类中来的 IsCladPart = SB.IsCladPart; BaseDensity = SB.BaseDensity; CladDensity = SB.CladDensity; BaseMaterial = SB.BaseMaterial; CladMaterial = SB.CladMaterial; #endregion 通过将SB赋值给本类中属性Shell,用Shell来接收控件验证时得到的参数值,然后传值到下一个继承者 } /// <summary> /// 在底层使用时进行调用,必须在控件赋值后进行使用,否则无效 /// </summary> public void ShellSetting() { #region 上一个抽象类中的控件 if (TbBaseDensity != null) { TbBaseDensity.Validating -= TbDensity_Validating; TbBaseDensity.Validating += TbDensity_Validating; } if (TbCladDensity != null) { TbCladDensity.Validating -= TbDensity_Validating; TbCladDensity.Validating += TbDensity_Validating; } if (TbBaseMaterial != null) { TbBaseMaterial.Validating -= TbBaseMaterial_Validating; TbBaseMaterial.Validating += TbBaseMaterial_Validating; } if (TbCladMaterial != null) { TbCladMaterial.Validating -= TbCladMaterial_Validating; TbCladMaterial.Validating += TbCladMaterial_Validating; } if (CbxIsCladPart != null) { CbxIsCladPart.CheckedChanged -= CbxIsCladPlate_CheckedChanged; CbxIsCladPart.CheckedChanged += CbxIsCladPlate_CheckedChanged; } #endregion 上一个抽象类中的控件 #region 本类中的控件 if (TbShellDn != null) { TbShellDn.Validating -= TbShellDn_Validating; TbShellDn.Validating += TbShellDn_Validating; } if (TbShellTn != null) { TbShellTn.Validating -= TbShellTn_Validating; TbShellTn.Validating += TbShellTn_Validating; } if (CbxIsBasedOnOD != null) { CbxIsBasedOnOD.CheckedChanged -= CbxIsBasedOnOD_CheckedChanged; CbxIsBasedOnOD.CheckedChanged += CbxIsBasedOnOD_CheckedChanged; } #endregion 本类中的控件 } }
6.再下一级的类C中只需要管好自己类中属性的向下传递即可。
public class HeadBase : ShellBase { #region 属性设置 /// <summary> /// 封头类型 /// </summary> protected HeadType zHeadType; /// <summary> /// 封头类型 /// </summary> public HeadType HeadType { get { return zHeadType; } set { zHeadType = value; } } /// <summary> /// 封头最小厚度 /// </summary> protected double ztmin; /// <summary> /// 封头最小厚度 /// </summary> public double tmin { get { return ztmin; } set { ztmin = value; } } /// <summary> /// 封头标准,程序中直接设置 /// </summary> protected string zHeadStandard; /// <summary> /// 封头标准,程序中直接设置 /// </summary> public string HeadStandard { get { return zHeadStandard; } set { zHeadStandard = value; } } /// <summary> /// 封头直边 /// </summary> protected double zh; /// <summary> /// 封头直边 /// </summary> public double h { get { return zh; } set { zh = value; } } #endregion #region 控件属性 public TextBox TbTmin { get; set; } public TextBox TbHeadStandard { get; set; } public TextBox Tbh { get; set; } #endregion 控件属性 #region 控件事件 /// <summary> /// 在下一级的实例中执行数据验证 /// </summary> public void HeadSetting() { if (Tbh != null) { Tbh.Validating += Tbh_Validating; } if (TbTmin != null) { TbTmin.Validating += TbTmin_Validating; } if (TbHeadStandard != null) { TbHeadStandard.Validating += TbHeadStandard_Validating; } } private void TbHeadStandard_Validating(object sender, System.ComponentModel.CancelEventArgs e) { HeadStandard = TbHeadStandard.Text; } private void TbTmin_Validating(object sender, System.ComponentModel.CancelEventArgs e) { if (TbTmin.Text == "") { ErrShow.Clear(); return; } double val = 0; double.TryParse(TbTmin.Text, out val); if (val <= 0) { ErrShow.SetError(TbTmin, "封头最小厚度应大于0"); e.Cancel = true; } else if (Tn > 0) { if (val > Tn) { ErrShow.SetError(TbTmin, "封头最小厚度应小于公称厚度"); e.Cancel = true; } else { tmin = val; ErrShow.Clear(); } } else { tmin = val; ErrShow.Clear(); } } private void Tbh_Validating(object sender, System.ComponentModel.CancelEventArgs e) { if (Tbh.Text == "") { ErrShow.Clear(); return; } double val = 0; double.TryParse(Tbh.Text, out val); if (val < 25) { ErrShow.SetError(Tbh, "封头直边应大于等于25mm"); e.Cancel = true; } else { h = val; ErrShow.Clear(); } } #endregion 控件事件 public HeadBase() { } /// <summary> /// /// </summary> /// <param name="V"></param> /// <param name="S"></param> /// <param name="SB"></param> public HeadBase(Vessel V, Space S, ShellBase SB) : base(V, S, SB) { } /// <summary> /// 继承容器类中的属性值 /// 继承腔体类中的属性值 /// 并且设置下一级类中的属性值 /// </summary> /// <param name="V"></param> /// <param name="S"></param> /// <param name="HB"></param> public HeadBase(Vessel V, Space S, ShellBase SB, HeadBase HB) : base(V, S, SB) { #region 控件继承 if (HB.Tbh!=null) { Tbh = HB.Tbh; } if (HB.TbTmin != null) { TbTmin = HB.TbTmin; } if (HB.TbHeadStandard != null) { TbHeadStandard = HB.TbHeadStandard; } #endregion 控件继承 #region 属性传值 h = HB.h; tmin = HB.tmin; HeadStandard = HB.HeadStandard; #endregion 属性传值 } #region 锥形封头公用函数 public double wConeInArea(double Di, double Dis, double ang) { double angH = ang.DegreeToRadian(); double L = (Di / 2 - Dis / 2) / angH.SinH(); return ((Math.PI * L * (Di / 2 + Dis / 2)) * 1e-6).Round(2); } public double xConeVolume(double Di, double h1, double Dis, double h2, double R, double r, double ang, double tn) { double angH = ang.DegreeToRadian(); double a = angH.SinH() / 4; double b = (angH.SinH() * angH.CosH() + angH) / 2 - angH.SinH(); double c = 2 * angH.SinH() - Math.Pow(angH.SinH(), 3) / 3 - angH.SinH() * angH.CosH() - angH; double d = Math.PI * (a * Di * Di * R + b * Di * R * R + c * Math.Pow(R, 3)); double e = (Math.Pow(Di - 2 * R * (1 - angH.CosH()), 3) - Math.Pow(Dis + 2 * (1 - angH.CosH()) * (r + tn), 3)) * Math.PI / (24 * Math.Tan(angH)); double f = Math.PI * (a * Dis * Dis * (r + tn) - b * Dis * Math.Pow(r + tn, 2) + c * Math.Pow(r + tn, 3)); double g = Math.PI * Di * Di * h1 / 4; double i = Math.PI * Dis * Dis * h2 / 4; return ((d + e + f + g + i) * 1e-9).Round(3); } #endregion 锥形封头公用函数 }
7.再下级类D中也只需要管好自己类中属性的向下传递即可,本例中没有其它属性。
此类无关紧要,如果有也同“下级类”,此处省略。
8.调用类中应注意各实例的先后与赋值情况,否则容易导致出错。
public partial class Test1 : Form { Vessel V = null; Space S = null; ShellBase SB = null; HeadBase HB = null; HeadEllipseBase HEB = null; public Test1() { InitializeComponent(); } private void Test1_Load(object sender, EventArgs e) { V = new Vessel(); V.ErrShow = errShow; S = new Space(V); SB = new ShellBase(V, S); //凡是抽象类中的属性必须在其继承的类的实例中赋值才可以用 #region 控件赋值 SB.TbBaseDensity = tbBaseDensity; SB.TbCladDensity = tbCladDensity; SB.TbBaseMaterial = tbBaseMaterial; SB.TbCladMaterial = tbCladMaterial; SB.CbxIsCladPart = cbxIsCladPart; //ShellBase //而当前类的属性则也直接在其实例中进行赋值 SB.CbxIsBasedOnOD = cbxIsBasedOnOd; SB.TbShellDn = tbDn; SB.TbShellTn = tbTn; #endregion 控件赋值 #region 直接赋值测试 //SB.BaseDensity = 8; ////SB.CladDensity = 7; //SB.BaseMaterial = "SA-516 70"; ////SB.CladMaterial = "SA-240 316L"; //SB.IsCladPart = false; //SB.IsBasedOnOD = true; //SB.ShellDn = 1000; //SB.ShellTn = "10"; #endregion 直接赋值测试 //HeadBase HB = new HeadBase(V, S, SB); #region 控件赋值 HB.TbTmin = tbTmin; HB.TbHeadStandard = tbStandard; HB.Tbh = tbh; #endregion 控件赋值 #region 直接赋值测试 //HB.tmin = 8; //HB.HeadStandard = "GB/T 25198-2012"; //HB.h = 25; #endregion 直接赋值测试 HB.ShellSetting(); HB.HeadSetting(); } private void button2_Click(object sender, EventArgs e) { this.Close(); } private void btnCal_Click(object sender, EventArgs e) { HEB = new HeadEllipseBase(V, S, SB, HB); HEB.LblVolume = lblVolumne; HEB.LblMass = lblMass; HEB.LblInnerArea = lblInnerArea; HEB.LblOutterArea = lblOutArea; HEB.Cal(); HEB.SetResult(); } }
来源:https://www.cnblogs.com/swtool/p/5875971.html