类的继承
面向对象的三个基本特征是封装、继承、多态
三个类
Clerk:_name.Name;_department,Department;
Sales: _name.Name;_department,Department;_salestarget,Sakestarget;
Technical Support: _name.Name;_department,Department;
_satisfactionRate,SatisfactionRate;
上面3个类中都有相同的参数姓名和部门的字段 clerk 为父类其他为子类
对于类而言,所谓继承,就是子类包含父类的数据结构和行为方式,包括字段、属性、方法和事件。
尽管在子类本身的定义中没有包含这些定义,单仍然可以使用这些父类成员。
在类的继承中,被继承的类叫基类或父类,继承的类叫派生类或子类。
当一个类从另一个类派生出来时,派生类就自然具有基类数据成员、属性成员、和方法成员等,基类定义中这些成员的代码,已不需要再派生类定义中重写,在派生类的定义中,只需要编写基类定义中所不具有的代码即可。
目的:
1, 提高了代码的重用性。
2, 提高了程序设计的效率。
3, 为程序设置中的特别需要提供了编写代码的自由空间,从而提高了已有程序设计成果的可扩展性。
类继承注意的规则:
1, 单一性,只能继承一个类
2, 传递性(查看类图)点击解决档案,在项目上右键选择查看,查看类图
3, 派生类定义与基类同名的成员,则覆盖基类成员。
要使用new关键字可以隐藏基类中同名的成员.
如 public new string Name
{
Get;
Set;
}
4, 派生类自然继承基类的成员,但不能继承基类的构造函数的成员
//子类中不能继承父类中的构造函数,但是会默认地调用父类中的无参数的构造函数。
那要怎么实现调用呢?两种方法
1) 在父类中再写一个无参数构造函数,在每个子类当中都需要在进行一次构造函数的重写与各个字段的初始化。
2) 使用关键字:base()
如:public clerk(string name,int age):base(name,department)
{
This.Age=age; //不需要给name赋值,因为name是父类继承的
}
public enum Gander { 男, 女 } class Clerk { string _name; public string Name { get { return _name; } set { _name = value; } } int _age; public int Age { get { return _age; } set { _age = value; } } string _department; public string Department { get { return _department; } set { _department = value; } } Gander _gander; public Gander Gander { get { return _gander; } set { _gander = value; } } public void write() { Console.WriteLine("我叫{0},今年{1}岁,我是{2}生,我工作在{3}",this.Name,this.Age,this.Gander,this.Department); } public Clerk(string name,int age,Gander gander,string department) { this.Name = name; this.Age = age; this.Gander = gander; this.Department = department; } public Clerk() { } } class Rens:Clerk { string _xiaos; public string Xiaos { get { return _xiaos; } set { _xiaos = value; } } //1)构造函数的继承需要使用:base参数,在子类中写上一个构造函数,跟父类有相同的成员要:base掉 //这里面 name age gander department 跟父类相同的 所以在:base()中要写进去 //public Rens(string name,int age,Gander gander,string department,string xiaos):base(name,age,gander,department) //{ // this.Xiaos = xiaos; //} //2)构造函数只能继承没有参数的的,由于在Clerk类中写了构造函数,把原有的元参数的覆盖了,所以要在父类中重载一个构造函数 //之后再你需要的子类中,在写一遍你需要哪些参数的构造函数! public Rens(string name,int age,Gander gander,string department,string xiaos) { this.Xiaos=xiaos; } public void Rwrite() { Console.WriteLine("我叫{0},我今年{1}岁了,我是{2}生,我在{3}工作,我的销售额是{4}", this.Name, this.Age, this.Gander, this.Department, this.Xiaos); } } class Program { static void Main(string[] args) { Clerk duw = new Clerk("杜伟",28,Gander.男,"人事行政部"); Rens gaodm = new Rens("高冬梅",28,Gander.女,"商务部","5000"); duw.write(); gaodm.Rwrite(); Console.ReadKey(); } }
1, 如果用户希望一个类不被作为基类使用,那么就必须用sealed关键字。
2, 唯一的限制是抽象类不能作为封闭的类使用,因为抽象类的本质决定它们必须被作为基类使用。
3, 封闭类的作用是防止以为的派生操作,具体地说,因为编译器确定这个类没有任何派生类,所以可以将封闭类实例上的虚拟函数成员调用转换为非虚拟调用,
下面的例子是继承操作:
class Clerk { private string _name; //定义一个字段 public string Name //_name字段的属性 { get { return _name; } set { _name = value; } } private int _age; public int Age { get { return _age; } set { _age = value; } } public void write() { Console.WriteLine("您好,我叫{0},我今年{1}岁",this.Name,this.Age); } } } class Shangwu:Clerk //因为shangwu的类和clerk类有共同的字段 所以继承后我们就不用写相同的字段了 { private string department; public string Department { get { return department; } set { department = value; } } public void Swrite() { Console.WriteLine("您好,我叫{0},我今年{1}岁,我在{2}工作",this.Name,this.Age,this.Department); //因为是继承了Clerk类,所有Clerk里面的属性和方法我们也继承了 } } } class Program { static void Main(string[] args) { Shangwu xuhf = new Shangwu(); xuhf.Name = "许海峰"; xuhf.Age = 30; xuhf.Department = "商务部"; xuhf.Swrite(); Clerk duw = new Clerk(); duw.Name = "杜伟"; duw.Age = 28; duw.write(); Console.ReadKey(); } } }