继承是把基类的属性和方法延续到子类的过程, 继承除了把父类的方法带到子类,还允许子类对父类的方法进行派生。

如一个基类Animal, 则可有一个名为Fish的派生类和一个名为Bird的派生类,Fish是一个Animal, Bird也是,

每个派生类均表示基类Animal的不同专业化。

除了构造函数和析构函数以外,派生类隐式获得基类其余的所有成员, 实现代码重用, 同时派生类可增加更多的成员, 看代码:

public class WorkItem
    {
        private static int nextID;
        protected int ID { get; set; }
        protected TimeSpan jobLength { get; set; }
        protected string Title { get; set; }
        protected string Description { get; set; }
        public WorkItem()
        {
            ID = 0;
            Title = "Default title";
            Description = "Default description";
            jobLength = new TimeSpan();
        }
        static WorkItem()
        {
            nextID = 0;
        }
        public WorkItem(string title, string desc, TimeSpan joblen)
        {
            this.ID = GetNextID();
            this.Title = title;
            this.Description = desc;
            this.jobLength = joblen;
        }
        protected int GetNextID()
        {
            return ++nextID;
        }
        public void Update(string title, TimeSpan joblen)
        {
            this.Title = title;
            this.jobLength = joblen;
        }
        public override string ToString()
        {
            return string.Format("{0} - {1}", this.ID, this.Title);
        }
    }

    public class ChangeRequest : WorkItem
    {
        protected int originalItemID { get; set; }
        public ChangeRequest() { }
        public ChangeRequest(string title, string desc, TimeSpan jobLen, int originalID)
        {
            this.ID = GetNextID();
            this.Title = title;
            this.Description = desc;
            this.jobLength = jobLen;
            this.originalItemID = originalID;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            WorkItem item = new WorkItem("Fix Bugs",
                                         "Fix all bugs in my source code branch",
                                         new TimeSpan(3, 4, 0, 0));
            ChangeRequest change = new ChangeRequest("Change design of base class",
                                                     "Add members to base class",
                                                     new TimeSpan(4,0,0),1);
            Console.WriteLine(item.ToString());
            Console.WriteLine(change.ToString());
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }

    当基类将方法声明为Virtual时,派生类可以用自己的实现重写方法, 如果为基类的成员声明为abstract, 则在直接继承自该类的任何非抽象类中都要重写此方法。 对于抽象类,它继承抽象成员而不实现他们。 抽象成员和徐程远是多态性的基础,多态性是面向对象的变成的第二个主要特性。

如果希望禁止通过new关键字直接进行实例化,可以将类声明为abstract. 这样仅当从该类派生新类时才会使用这个类。  签名指定参数和返回值,但没有实现(方法体)。 抽象类不必包含抽象成员, 但如果某个类确实包含抽象成员,则该类自身必须声明为抽象类。 

派生类可以访问基类的公共成员,受保护成员,内部成员和受保护内部成员, 即使派生类继承基类的私有成员, 仍不能访问这些成员, 但是, 所有私有成员在派生类中仍然存在,且执行与基类自身相同的工作,例如,假定一个受保护基类方法访问私有字段。要是集成的基类方法正常工作,派生类必须要有该字段。

派生类可以通过以相同名称和签名声明基类成员来隐藏这些成员.