抽象可以通过抽象类或接口来实现。
abstract
关键字用于类和方法:
- 抽象类:是一个受限类,不能用于创建对象(要访问它,必须从另一个类继承)。
- 抽象方法:只能在抽象类中使用,并且它没有主体。主体即具体实现由派生类(继承自)提供。
抽象类可以有抽象方法和实现方法,至少有一个抽象方法。
试图讲一个抽象类Employee来实例化,错题提示如下;
- 示例:员工工资统计程序
现在有四类员工:
- 固定薪水员工 2.计时员工 3.提成员工 4.底薪+提成员工
经过分析知道:
1.所有员工都有一些共同的信息,【姓名】【工号】这两个作为字段成员,一个抽象Earning()方法作为计算薪酬,一个重写的toString()来显示基本信息;
所有定义一个抽象类,作为上述4类员工的基类,包含2个成员变量,1个构造函数,1个重写的overide string ToString()方法:
/// <summary> /// 基类Employee /// </summary> public abstract class Employee//创建抽象的基类 { protected Employee(string name, string ssd)//构造函数 { Name = name; SSD = ssd; } public string Name { get;private set; } public string SSD { get;private set; } public override string ToString()//重写方法 { return string.Format($"姓名:{Name}\n工号:{SSD}"); } public abstract decimal Earning();//抽象方法 }
2.接下来,定义第一个固定薪酬员工类,它将继承自上述的Employee基类,固定薪酬员工,它相比基类多了一个薪酬monthSalary,作为字段成员,并为其创建属性,注意在set时使用private修饰,表示为私有,不可外部修改;构造方法,值得注意的事需要也把继承自基类的参数name和ssd采用 :base(name,ssd)赋值;
/// <summary> /// 1固定薪水员工 /// </summary> public class MonthEmployee:Employee { private decimal monthSalary; public decimal MonthSalary//属性 { get { return monthSalary; } set { monthSalary = value > 0 ? value : 0; }//注意这里的选择表达式是冒号: } public MonthEmployee(string name, string ssd, decimal salary):base(name,ssd)//构造函数 { MonthSalary = salary; } public override decimal Earning() { return MonthSalary; } public override string ToString() { return string.Format($"定薪员工>>\n{base.ToString()}\n工资:{MonthSalary:C}"); } }
3.同上,定义第2类员工:计时员工,它相比基类多了2个字段,1个是小时工资,1个是工作时厂,代码如下:
/// <summary> ///2 时薪员工 /// </summary> public class HourlyEmployee:Employee { private double hours; private decimal hourSalary; public HourlyEmployee(string name,string ssd,double hours, decimal hourSalary):base(name,ssd) { this.hours = hours; this.hourSalary = hourSalary; } public double Hours { get { return hours; } private set { hours = value > 0 ? value : 0; } }//属性1 public decimal HourSalary { get { return hourSalary; } private set{hourSalary = value > 0 ? value : 0; }}//属性2 public override decimal Earning() { if (hours <= 40) { return hourSalary * (decimal)hours; } else { return 40 * hourSalary + (decimal) (hours - 40) * hourSalary*1.5M;//超过40H加班费 } } public override string ToString() { return string.Format($"时薪员工>>\n{base.ToString()}\n工时:{Hours}\n工资:{Earning():C}"); } }
4.同上,定义第3类员工:提成员工,它相比基类多了2个字段,1个是销售额,1个是提成比例,代码如下:
/// <summary> /// 3提成员工 /// </summary> public class SaleEmployee : Employee { private decimal sale; private decimal saleRatio; public decimal Sale { get { return sale; }private set { sale = value > 0 ? value : 0; } } public decimal SaleRatio { get { return saleRatio; } private set { saleRatio = value > 0 ? value : 0; } } public SaleEmployee(string name, string ssd, decimal sale, decimal saleRatio) : base(name, ssd) { this.Sale = sale; this.SaleRatio = saleRatio; } public override decimal Earning() { return sale * saleRatio; } public override string ToString() { return string.Format($"提成员工>>\n{ base.ToString()}\n销售额:{sale}\n工资:{Earning()}"); } }
5.接下来,定义第4类员工底薪+提成员工,此类员工在上述提成员工的基础上,外加了一部分底薪;所以,此类派生自上述SaleEmployee类;但他多了一个字段底薪;
/// <summary> /// 4底薪提成员工 /// </summary> public class BaseSaleEmployee : SaleEmployee { private decimal baseSalary; public decimal BaseSalary { get { return baseSalary; } private set { baseSalary = value > 0 ? value : 0; } } public BaseSaleEmployee(string name, string ssd, decimal sale, decimal saleRatio,decimal baseSalary) : base(name, ssd,sale,saleRatio) { this.BaseSalary = baseSalary; } public override decimal Earning() { return Sale * SaleRatio+baseSalary; } public override string ToString() { return string.Format($"底薪+提成员工>>\n{ base.ToString()}\n底薪:{baseSalary}"); } }
如此,4类员工+1个抽象基类员工全部定义设计完成。在VS中,可以在类视图选中右键如下图所以,查看类图(PS:如果右键没有这个选项功能,是vs缺少安装组件,参考连接:VS 2019如何查看类图_@2206的博客-CSDN博客_vs查看类图
最后:在主程序演示使用以上类;
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var EP1 = new MonthEmployee("王猛","1111",800M); 6 var EP2 = new HourlyEmployee("李毅", "2222", 70,20M); 7 var EP3 = new SaleEmployee("张宇", "3333", 15070, 0.05M); 8 var EP4 = new BaseSaleEmployee("赵雄", "4444", 17070, 0.04M,500); 9 10 Employee[] emp = new Employee[4]; 11 emp[0] = EP1; emp[1] = EP2; emp[2] = EP3; emp[3] = EP4; 12 13 Console.WriteLine("===============如下是数组打印内容============="); 14 int i = 0; 15 foreach (var item in emp) 16 { 17 i++; 18 Console.WriteLine(item); 19 Console.WriteLine("-----------------------{0}-----------------------", i); 20 } 21 Console.ReadLine(); 22 } 23 }
输出结果:
至此,抽象类与派生类的学习总结完成。
最后,感谢B站的免费视频和视频中西安交大的崔老师;链接:C#程序设计 西安交通大学 C#基础入门教程_哔哩哔哩_bilibili
^(* ̄(oo) ̄)^祝大家学习愉快!