C#-继承

继承

用来解决类与类之间的代码冗余。

我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类。如下代码:

public class Person//父类Person
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        private char _gender;
        public char Gender
        {
            get { return _gender; }
            set { _gender = value; }
        }
        private int _age;
        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }
        public void CHLSS()
        {
            Console.WriteLine("CHLSS");
        }
        public Person(string name,char gender,int age)//父类的构造函数
        {
            this.Name = name;
            this.Gender = gender;
            this.Age = age;
        }
    }
    public class Studert:Person//子类Student继承于父类Person
    {
        private int _id;
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }
        public void Study()
        {
            Console.WriteLine("我会学习");
        }
        public Studert(string name,char gender,int age,int id)
            :base(name,gender,age)//继承父类的构造函数
        {
            this.Id = id;
        }
    }
    public class Teacher:Person//子类Teacher继承于父类Person
    {
        private decimal _salary;
        public decimal Salary
        {
            get { return _salary; }
            set { _salary = value; }
        }
        public void Teach()
        {
            Console.WriteLine("我会教书");
        }
        public Teacher(string name,char gender,int age,decimal salary)
            :base(name,gender,age)//继承父类的构造函数
        {
            this.Salary = Salary;
        }
    }
    public class Driver:Person//子类Driver继承于父类Person
    {
        private double _driveTime;
        public double DriveTime
        {
            get { return _driveTime; }
            set{ _driveTime = value; }
            
        }
        public void Drive()
        {
            Console.WriteLine("我会开车");
        }
        public Driver(string name,char gender,int age,double driverTime)
            :base(name,gender,age)//继承父类的构造函数
        {
            this.DriveTime = driverTime;
        }
    }

上面代码中,Person作为一个父类,封装了属性Name,Gender,Age,这三个属性对于Student类,Techer类以及Driver类都是服复用的;如果没有继承这个概念,Student类,Techer类,Driver类以及后续类似可能需要声明属性Name,Gender,Age的各种类来讲,都需要在各自的类里面单独声明属性Name,Gender,Age,这样程序就有大量的冗余代码。现在我们用一个名为Person的类来封装这段可能被反复重复声明的属性Name,Gender,Age,此时Person类我们称为父类(或 基类),其他类(Student、Teacher、Driver...)通过继承Person类,来继承Person类里面的所有的属性(Name,Gender,Age),而不是像以往一样单独在各自类中重复的声明属性,Student、Teacher、Driver这些继承于父类的类称为子类(或派生类)。

继承的语法:

在声明类的后面加上“:父类名”即可,代码如下:

public class Studert:Person//子类Student继承于父类Person
    {
        private int _id;
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }
        public void Study()
        {
            Console.WriteLine("我会学习");
        }
        public Studert(string name,char gender,int age,int id)
            :base(name,gender,age)//继承父类的构造函数
        {
            this.Id = id;
        }
    }

上面代码可以看出Student类继承于名为Person的父类,子类既可以继承父类的成员也可以拥有属于自己的成员。Student类中不仅有继承于Person类的属性(Name,Gender,Age)还有自己特有的属性Id和方法Study()。

剖析:

1、子类继承了父类,那么子类从父类那里继承过来了什么?
答:子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段。如果希望继承父类的字段,那么父类的字段需要公有化,但是不建议此类操作。

2、子类有没有继承父类的构造函数?
答:子类并没有继承父类的构造函数。但是,子类会默认的调用父类无参数的构造函数。子类在创建对象的时候,子类会先在子类中创建父类对象,让子类可以使用父类中的成员。
所以,会出现这种情况,如果在父类中重新写了一个有参数的构造函数之后,那个默认的无参数的构造函数就会被干掉,子类就调用不到了,所以子类会报错。
出现这种情况我们要怎样解决?

方法(1)、在父类中重新写一个无参数的构造函数。
方法(2)、在子类中显示的调用父类的构造函数,使用关键字:base(),如下代码:

public class Teacher:Person//子类Teacher继承于父类Person
    {
        private decimal _salary;
        public decimal Salary
        {
            get { return _salary; }
            set { _salary = value; }
        }
        public void Teach()
        {
            Console.WriteLine("我会教书");
        }
        public Teacher(string name,char gender,int age,decimal salary)
            :base(name,gender,age)//继承父类的构造函数
        {
            this.Salary = Salary;
        }
    }

上面代码Teacher类继承于Person。Techer类的构造函数Teacher()是有参的,通过加上关键字“:base()”的操作,去调用Person类的构造函数。

继承的两个特性: 
1、继承的单根性:一个子类只能有一个父类。
2、继承的传递性:一个子类可以被其他类继承,从何成为其他类的父类。

拓展:

1、可以通过查看类图来查来类的继承关系;

2、object是所有类的基类。

3、new关键字
1),创建对象
2).隐藏从父类那里继承过来的同名成员。隐藏的后果就是子类调用不到父类的成员。

posted @ 2019-03-16 13:01  杯子旁边有手机  阅读(180)  评论(0编辑  收藏  举报