详解C#面相对象编程中的继承特性
继承(加上封装和多态性)是面向对象的编程的三个主要特性(也称为“支柱”)之一。 继承用于创建可重用、扩展和修改在其他类中定义的行为的新类。其成员被继承的类称为“基类”,继承这些成员的类称为“派生类”。派生类只能有一个直接基类。但是,继承是可传递的。如果 classb 派生出 classc,classa 派生出 classb,则 classc 会继承 classb 和 classa 中声明的成员。
注意
结构不支持继承,但可以实现接口。
从概念上来说,派生类是基类的特例。 例如,如果您有一个基类 animal,则可以有一个名为 mammal 的派生类和一个名为 reptile 的派生类。 mammal 是一个 animal,reptile 也是一个 animal,但每个派生类均表示基类的不同专用化。
定义一个类从其他类派生时,派生类隐式获得基类的除构造函数和析构函数以外的所有成员。因此,派生类可以重用基类中的代码而无需重新实现这些代码。可以在派生类中添加更多成员。派生类以这种方式扩展基类的功能。
下图演示一个 workitem 类,该类表示某业务流程中的一个工作项。和所有的类一样,该类派生自 system.object 并继承其所有方法。 workitem 添加了自己的五个成员。其中包括一个构造函数,因为构造函数不能继承。类changerequest 继承自 workitem 并表示特定种类的工作项。 changerequest 在它从 workitem 和 object 继承的成员中另外添加了两个成员。它必须添加其自己的构造函数,还添加 originalitemid。利用属性 originalitemid,可将 changerequest 实例与更改请求将应用到的原始 workitem 相关联。
类继承
下面的示例演示如何以 c# 表示上图所示的类关系。该示例还演示 workitem 如何重写虚方法 object.tostring,以及 changerequest 类如何继承该方法的 workitem 实现。
// workitem implicitly inherits from the object class. public class workitem { // static field currentid stores the job id of the last workitem that // has been created. private static int currentid; //properties. protected int id { get; set; } protected string title { get; set; } protected string description { get; set; } protected timespan joblength { get; set; } // default constructor. if a derived class does not invoke a base- // class constructor explicitly, the default constructor is called // implicitly. public workitem() { id = 0; title = "default title"; description = "default description."; joblength = new timespan(); } // instance constructor that has three parameters. public workitem(string title, string desc, timespan joblen) { this.id = getnextid(); this.title = title; this.description = desc; this.joblength = joblen; } // static constructor to initialize the static member, currentid. this // constructor is called one time, automatically, before any instance // of workitem or changerequest is created, or currentid is referenced. static workitem() { currentid = 0; } protected int getnextid() { // currentid is a static field. it is incremented each time a new // instance of workitem is created. return ++currentid; } // method update enables you to update the title and job length of an // existing workitem object. public void update(string title, timespan joblen) { this.title = title; this.joblength = joblen; } // virtual method override of the tostring method that is inherited // from system.object. public override string tostring() { return string.format("{0} - {1}", this.id, this.title); } } // changerequest derives from workitem and adds a property (originalitemid) // and two constructors. public class changerequest : workitem { protected int originalitemid { get; set; } // constructors. because neither constructor calls a base-class // constructor explicitly, the default constructor in the base class // is called implicitly. the base class must contain a default // constructor. // default constructor for the derived class. public changerequest() { } // instance constructor that has four parameters. public changerequest(string title, string desc, timespan joblen, int originalid) { // the following properties and the getnexid method are inherited // from workitem. this.id = getnextid(); this.title = title; this.description = desc; this.joblength = joblen; // property originalitemid is a member of changerequest, but not // of workitem. this.originalitemid = originalid; } } class program { static void main() { // create an instance of workitem by using the constructor in the // base class that takes three arguments. workitem item = new workitem("fix bugs", "fix all bugs in my code branch", new timespan(3, 4, 0, 0)); // create an instance of changerequest by using the constructor in // the derived class that takes four arguments. changerequest change = new changerequest("change base class design", "add members to the class", new timespan(4, 0, 0), 1); // use the tostring method defined in workitem. console.writeline(item.tostring()); // use the inherited update method to change the title of the // changerequest object. change.update("change the design of the base class", new timespan(4, 0, 0)); // changerequest inherits workitem's override of tostring. console.writeline(change.tostring()); // keep the console open in debug mode. console.writeline("press any key to exit."); console.readkey(); } }
输出:
1 - fix bugs 2 - change the design of the base class
上一篇: 微信小程序保存多张图片的实现方法