继承的定义与使用
继承是软件复用的一种形式。使用继承可以复用现有类的数据和行为,为其赋予新功能而创建出新类。复用能节省程序开发的时间,能重用经过实践检验和调试的高质量代码,提高系统的质量。
在现有类(称为直接基类、父类)上建立新类(称为派生类、子类)的处理过程称为继承。
派生类能自动获得基类的除了构造函数和析构函数以外的所有成员,可以在派生类中添加新的属性和方法扩展其功能。
// 语法:<访问修饰符> class派生类名: 基类名{// 类的代码}
Person.cs(Person类)
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InheritDemo{public class Person{private string _id; // 声明身份证号码字段 _idpublic string Id // 声明身份证号码属性ID{get { return _id; } // get访问器,获取身份证号码字段值set { _id = value; } // set访问器,设置身份证号码字段值}private string _name; // 声明姓名字段public string Name // 声明姓名属性{get { return _name; } // get访问器,获取姓名字段值set { _name = value; } // set访问器,设置身份证号码字段值}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 void Display() // 基类的公有方法,用于输出Person对象的姓名、年龄与性别信息{Console.WriteLine(\"{0}是{1}性,年龄为{2}\", this._name, this._gender, this._age);}public Person() // 定义无参构造函数{ }public Person(string name, int age, string gender) // 定义有参构造函数{_name = name;_age = age;_gender = gender;}}public class Student: Person// 创建派生类,派生自Person类{// 定义派生类自己的属性private string _class; // 定义表示学生班级的字段_classpublic string Class // 定义设置和获取班级信息的属性Class{get { return _class; }set { _class = value; }}private string _department; // 定义学生所属系的字段public string Deparement // 定义学生所属系的属性{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(\"好好学习,天天向上!\");}}}
Teacher.cs(Teacher类)
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InheritDemo{class Teacher: Person{private string _tid; // 声明字段教师编号public string Tid // 定义教师编号属性{get { return _tid; }set { _tid = value; }}private string _course; // 声明课程字段public string Course // 定义课程属性{get { return _course; }set { _course = value; }}// 教师派生类的方法public void Teaching(){Console.WriteLine(\"正在上课中...\");}}class DoubleStudent: Student{private string _sndBachelor; // 声明第二学位名称字段public string SndBachelor // 声明第二学位属性{get { return _sndBachelor; }set { _sndBachelor = value; }}public DoubleStudent() // 无参构造函数{ }public void UsaBachelor() // 定义方法{Console.WriteLine(\"正在攻读xxx大学学位\");}}}
Program.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InheritDemo{class Program{static void Main(string[] args){Console.WriteLine(\"Person类:\");Person objPerson = new Person(\"张三\", 18, \"男\");objPerson.Display(); // 调用Display显式对象信息 --> 张三是男性,年龄为18Console.WriteLine(\"Student类:\");Student objStudent = new Student(){Name = \"李四\",Age = 18,Gender = \"女\"};objStudent.Display(); // 访问基类的Display方法 --> 李四是女性,年龄为18objStudent.Study(); // 调用派生类方法 --> 好好学习,天天向上!Console.ReadKey();Console.WriteLine(\"Teacher类\");Teacher objTeacher = new Teacher(){Name = \"Mary\",Age = 26,Gender = \"女\"};objTeacher.Display(); // 访问基类的Display方法objTeacher.Teaching(); // 访问Teacher类的方法Console.WriteLine(\"DoubleStudent类\");DoubleStudent objSpecial = new DoubleStudent(){Name = \"Bliss\",Age = 22,Gender = \"女\"};objSpecial.Display(); // 访问Person类方法objSpecial.Study(); // 访问Student类方法objSpecial.UsaBachelor(); // 调用DoubleStudent类方法Console.ReadKey();}}}
继承的特性
C#中的继承主要有以下3种特性:
- 继承的可传递性
如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中的成员。
如示例代码中DoubleStudent类的基类是Student,Student的基类是Person,因此DoubleStudent类可以继承Person类中的成员。
派生类是对基类的扩展,在派生类中可以添加新成员,但不能去除已经继承的成员。 - 继承的单一性
继承的单一性是指派生类只能从一个基类中继承,不能同时继承多个基类。C#不支持类的多重继承,也就是说儿子只能有一个亲生父亲,不能同时拥有多个亲生父亲。但可以通过接口实现多重继承。(具体后续学习研究) - 继承中的访问修饰符
访问性修饰符 | 类内部 | 派生类 |
---|---|---|
public(公有访问) | 访问不受限制 | 不受限制 |
protected(保护访问) | 访问仅限于包含类或从包含类派生的类型(本类成员和子类可以访问,实例不能访问) | 可以访问 |
internal(内部访问) | 访问仅限于当前项目 | 可以访问 |
protected internal(内部保护访问) | 访问从包含类派生的当前项目或类型(仅限于本项目或子类) | 可以访问 |
private(私有访问) | 访问仅限于包含类型(仅限于本类成员,子类、实例都不能访问) | 不可访问 |
this和base关键字
基类中只有被public、protected、internal修饰的成员才可以被访问,这些成员包括任何基类的字段、属性、方法和索引器,但是基类的构造函数和析构函数是不能被继承的。如果要继承基类的构造函数,必须使用base关键字来实现。
C#中的base关键字代表基类,使用base关键字可以调用基类的构造函数、属性和方法。
语法:派生类构造函数: base(参数列表)
// 给上述示例Student类添加一个有参构造函数public Student(string name, int age, string gender):base(name, age, gender) // 构造函数{// 通过base(name, age, gender)调用基类的构造函数}
// 使用base关键字调用基类方法语法base: 基类方法// 示例:public Student(string name, int age, string gender) : base(name, age, gender) // 调用基类的构造函数{ }
相对于base来说,this关键字是引用类的当前实例。
public Person(string name, int age, string gender) // 构造函数{this._name = name;this._age = age;this._gender = gender;}
派生类继承基类的属性和方法,从而使创建派生类变得简单,可实现代码的重用。
基类对象可以引用派生类对象,也就是派生类对象可以赋值给基类对象变量。
对这个特性可以这样理解:儿子继承于父亲,父亲也可以代表儿子处理事务,这就实现了基类对象引用派生类对象。
class Father(){...}class Son: Father{...Public void CallDaddy() // 派生类方法{}}
Son objSon = new Son();Father objFather = new Father();objFather = objSon; // 派生类对象objSon赋值给基类对象 objFather((Son)objFather).CallDaddy(); // 基类对象调用派生类的方法
父类对象引用子类实例时,注意要把父类型转为子类型,否则就会出错。
- 点赞
- 收藏
- 分享
- 文章举报
Yeats.NeverGiveUp发布了12 篇原创文章 · 获赞 0 · 访问量 165私信关注