XM的小窝


 

C#之继承的基本概念

概念

我们可能会在一些类中,写一些重复的成员,可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类,这是继承的作用
Q: 子类继承了父类,那么子类从父类那里继承过来了什么?

A: 首先,子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段

Q: 子类有没有继承父类的构造函数?

A:子类并没有继承父类的构造函数,但是,子类会默认的调用父类的无参数的构造函数,创建父类对象,让子类能够使用父类的成员,所以,如果在父中重写了一个有参数的构造函数后,无参构造器会被覆盖掉,子类就调用不了无参的构造器了,子类就会报错

解决办法:
1.手动创建一个无参构造器,实现重载
2.在子类中显式的调用父类的构造函数,使用关键字:base()

P.S: object 是一切类型的基类

继承的特性

单根性:一个子类只能有一个父类
传递性:派生类会从基类那里继承特性
子类可以隐藏掉父类的方法 (子类内的方法使用new关键字修饰)

代码演示

class Program
{
    static void Main(string[] args)
    {
        //强制转换为Driver之后,relation字段就不能调用了,因为Driver类中没有相应字段,但可以通过构造器重载来解决参数多余的问题
        Person P1 = (Person)new Driver_son("司机", 48, 15);
        Console.WriteLine("姓名:{0} 年龄:{1} 驾龄无法获取", P1.Name, P1.Age);

        Driver_son Dson = new Driver_son("司机的儿子", 18, 5, "父子");
        //调用基类Person的方法
        Dson.Prop();
        //调用SonSays方法
        Dson.SonSays();
        //调用父类Driver的Use方法,但是父类中的Use方法被子类隐藏了,并且用new关键字修饰,所以调用的是子类的Use方法
        Dson.Use();
        Console.WriteLine(Dson.Name + " " + Dson.Age + " " + Dson.Driveage + " " + Dson.Relation);
        Teacher teacher = new Teacher();
        teacher.Name = "老师";
        teacher.Age = 40;
        teacher.Teachage = 5;
        Console.WriteLine("我是{0},我{1}了,我教书{2}年了", teacher.Name, teacher.Age, teacher.Teachage);
        teacher.Use();

    }
}
//基类
class Person
{
    //在这里直接使用有参构造器会引起子类的报错,详情见上方注释
    public Person(string name, int age)
    {
        this.Name = name;
        this.Age = age;
    }
    //使用一个无参构造器解决,其原理个人猜测是利用了方法的重载
    public Person()
    {

    }
    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
    private int _age;
    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }
    public void Prop()
    {
        Console.WriteLine("我是人");
    }
}
//派生类
class Teacher : Person
{
    //注意,子类无法继承父类的私有字段和方法
    private int _teachage;
    public int Teachage
    {
        get { return _teachage; }
        set { _teachage = value; }
    }
    public void Use()
    {
        Console.WriteLine("我会教书");
    }
}
class Driver : Person
{
    public Driver(string name, int age, int drivage) : base(name, age)
    {
        this.Driveage = drivage;
    }
    //重载
    public Driver() { }
    private int _driveage;
    public int Driveage
    {
        get { return _driveage; }
        set { _driveage = value; }
    }
    public void Use()
    {
        Console.WriteLine("Driver类说,我会开车");
    }
}
class Driver_son : Driver
{
    //有参构造器,使用base引用父类的构造函数获取需要的参数
    public Driver_son(string name, int age, int da, string relation) : base(name, age, da)
    {
        this.Relation = relation;
    }
    //重载构造器
    public Driver_son(string name, int age, int da) : base(name, age, da)
    {

    }
    private string _relation;
    public string Relation
    {
        get { return _relation; }
        set { _relation = value; }
    }
    //子类会隐藏掉父类的Use  使用new关键字隐藏掉父类
    public  new void Use()
    {
        Console.WriteLine("Driver_son说,我会开车");
    }
    public void SonSays()
    {
        Console.WriteLine("我是司机的儿子");
    }
}
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注