|
继承是软件复用的一种形式。使用继承可以复用现在类的数据和行为,为其赋予新功能而创建出新类。复用能节约开发的时间,能复用经过实践检验和调试的高质量代码,提高系统的质量。
继承的定义和使用
在现有类(基类、父类)上建立新类(派生类、子类)的过程称为继承。派生类能自动获得基类的除构造函数和析构函数函数以外的所有成员,可以在派生类中添加新的属性和方法拓展其功能。
- 通过继承创建派生类语法格式如下:
<访问修饰符> class 派生类名:基类名 { //类的代码 }
在实际中,一个类的对象也是类外一个类的对象。例如,一个矩形类属于四边形。也可以说矩形是从四边形类继承而来的。四边形类是基类,矩形类是派生类。再如,教师类和学生类都可以从人这个来派生,讲师和教授可以从教师类派生,研究生和本科生可以从学生类派生而得到。
实例
定义基类Person,然后通过继承创建派生类Student。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace test { class Program { static void Main(string[] args) { Person person1 = new Person("小明", 18, "男"); person1.DisPlay(); Student Stu1 = new Student(); Stu1.Name = "小王"; Stu1.Age = 19; Stu1.Gender = "男"; Stu1.Class = "2014级机械工程专业"; Stu1.DisPlay(); Stu1.Study(); Console.ReadKey(); } } public class Person { private String _id; //身份证号码字段id public string ID //身份证号码属性id { get { return _id; } set { _id = value; } } private String _name; //姓名字段 public string Name //姓名属性 { get { return _name; } set { _name = value; } } private int _age; //年龄字段 public int Age //年龄属性 { get { return _age; } set { _age = value; } } private String _gender; //性别字段 public string Gender //性别属性 { get { return _gender; } set { _gender = value; } } public Person() //无参构造函数 { } public Person(string name,int age,string gender) //有参构造函数 { _name = name; _age = age; _gender = gender; } public void DisPlay() //基类共用方法,显示人的信息 { Console.WriteLine("{0}是{1}性,年龄为{2}岁",this._name,this._gender,this._age); } } public class Student :Person //创建派生类,派生自person类 { //定义派生类自己的属性 private String _class; //学生班级 public string Class { get { return _class; } set { _class = value; } } private String _department; //学生院系 public string Department { get { return _department; } set { _department = value; } } private String _no; //学生学号 public string No { get { return _no; } set { _no = value; } } public Student() // 无参构造函数 { } //定义派生类独有方法Study,表示在校学习 public void Study() { Console.WriteLine("学生在校学习"); } } }
运行结果:
继承的特性
继承的可传递性
如果C从B派生,B又从A派生,那么C不仅继承B中声明的成员,同样也继承了A中的成员。
派生类是基类的拓展,在哦爱生类中可以添加新成员,但是不能去除已经继承的成员。继承的单一性
继承的单一性是指派生类只能从一个基类中继承,不能同时继承多个基类。C#不支持多重继承。多重继承可以通过接口实现。
继承中的访问修饰符
在前面的帖子已经讲到,C#中的访问修饰符有:public、protected、private、internal和protected internal5种,可以使用这些访问修饰符指定5个可访问级别。
在继承时各个访问修饰符的访问权限如下:访问性修饰符 类内部 派生类 public 访问不受限制 不受限制 protected 访问仅限于包含类或从包含类派生的类型 可以访问 internal 访问仅限于当前项目 可以访问 protected internal 访问仅限于从包含类派生的当前项目或类型 可以访问 private 访问仅限于包含类 不可访问 基类中的成员如果用public修饰,任何类都可以访问;如果用private修饰,他讲作为私有成员,只有类本身可以访问,其他任何类都无法访问。在C#中,我们是用protected修饰符,使用这个访问修饰符的成员可以被其派生类访问,而不允许其他非派生类访问。
base和this关键字
base
从上面的介绍我们知道,基类中只有被public、protected、internal修饰的成员才能被访问,这些成员包括任何基类的字段、属性、方法和索引器,但是基类的构造函数和析构函数是不能继承的。如果要继承基类的构造函数,必须使用base关键字来实现。在C#中的base关键字代表基类,使用base关键字可以调用基类的构造函数、属性和方法。
- 使用base关键字调用基类构造函数的语法如下:
public Student(string name,int age,string gender) : base(name, age, gender) { //通过base(name, age, gender)调用基类的构造函数 }
- 使用base关键字调用基类方法的语法如下:
base:基类方法();
this
相对于base来说,this关键字是引用类的当前实例。
如在上段程序中的构造函数中添加this,可以写成一下形式:public Person(string name,int age,string gender) //有参构造函数 { this._name = name; this._age = age; this._gender = gender; }
this关键字引用类的当前实例,还可以用做拓展方法的第一个参数的修饰符,this关键字还可以调用自己的构造方法。使用this关键字可以使代码的编写简单化,不容易出错。在类的方法里使用this关键字,在后面输入一个“.”符号后,系统会把本类所能调用的非静态方法和变量都显示出来供选择,这样可以提高编码效率。
派生类继承基类的属性方法,从而使创建派生类变得简单,可以实现代码的重用。继承还有一个重要的特性,即基类对象可以引用派生类对象,也就是派生类对象可以赋值给基类对象变量。
实例
使用base和this改进上面的程序
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace test { class Program { static void Main(string[] args) { Person person1 = new Person("小明", 18, "男");//利用有参构造函数创建对象 person1.DisPlay(); //调用DisPlay方法显示信息 Student Stu1 = new Student("小美",19,"女"); //利用有参构造函数创建对象 Stu1.Class = "2014级护理专业"; Stu1.DisPlay(); //调用基类DisPlay方法显示信息 Stu1.Study(); Person person2 = new Person(); //创建person类对象 person2 = Stu1; //把派生类对象赋值给基类对象 person2.DisPlay(); //调用DisPlay方法显示信息 ((Student)person2).Study(); //基类对象调用派生类的方法 Console.ReadKey(); } } public class Person { private String _id; //身份证号码字段id public string ID //身份证号码属性id { get { return this._id; } set { this._id = value; } } private String _name; //姓名字段 public string Name //姓名属性 { get { return this._name; } set { this._name = value; } } private int _age; //年龄字段 public int Age //年龄属性 { get { return this._age; } set { this._age = value; } } private String _gender; //性别字段 public string Gender //性别属性 { get { return this._gender; } set { this._gender = value; } } public Person() //无参构造函数 { } public Person(string name,int age,string gender) //有参构造函数 { this._name = name; this._age = age; this._gender = gender; } public void DisPlay() //基类共用方法,显示人的信息 { Console.WriteLine("{0}是{1}性,年龄为{2}岁",this._name,this._gender,this._age); } } public class Student :Person //创建派生类,派生自person类 { //定义派生类自己的属性 private String _class; //学生班级 public string Class { get { return _class; } set { _class = value; } } private String _department; //学生院系 public string Department { get { return _department; } set { _department = value; } } private String _no; //学生学号 public string No { get { return _no; } set { _no = value; } } public Student() // 无参构造函数 { } public Student(string name,int age,string gender):base(name,age,gender) { // 调用基类的构造函数 } //定义派生类独有方法Study,表示在校学习 public void Study() { Console.WriteLine("学生在校学习"); } } }
运行结果:
------------------------------------------------------------------------------------------ 分割线 ------------------------------------------------------------------------------------------
- 博主简介:
- 工业自动化上位机软件工程师、机器视觉算法工程师、运动控制算法工程师。目前从业于智能制造自动化行业。 博主邮箱:2296776525@qq.com
- 帮忙点个赞吧。哈哈。