类的讲解2(继承)

--继承:子类实例化的时候,父类构造函数也会跟随执行

继承:属于面向对象三大特性之一(封装,继承,多态)
    /*
     * 父类中抽离"公共成员"
     * 子类中"扩展"特殊的成员
     * 
     * 基类:父类  Animal
     * 派生类:子类  Dog
     * 
     * 继承的核心思想:子类使用父类公开的属性和方法,同时拓展自己的特性
     */

先定义一个Animal类,之后用Dog类继承Animal类

//调用了无参的构造函数
Animal laohu = new Animal();
laohu.Name = "老虎";


//调用了带有参数的构造函数
Animal daxiang = new Animal(1, "大象");
//laohu和daxiang都属于Animal的实例,拥有独立的内存空间
Console.WriteLine(laohu.Name);
Console.WriteLine(daxiang.Name);


//实例化的同时进行初始化
Animal houzi = new Animal() { Id = 2, Name = "猴子" };
Console.WriteLine(houzi.Name);

public class Animal
{
    public int Id
    {
        get;
        set;
    }
    public string Name
    {
        get;
        set;
    }
    //构造函数
    public Animal()
    {
        Console.WriteLine("构造函数中实例化时调用,无参构造函数");
    }
    //构造函数,可以携带参数,一般都是公开的,没有返回值,函数名称和类名一样
    //与上面的Anmial都成为构造函数,构造函数可以有多个,名字相同,参数上有变化

    public Animal(int id, string name)
    {
        this.Id = id;
        this.Name = name;
        Console.WriteLine("这属于有参构造函数");
    }
    //virtual:虚方法,表示占用一个位置,子类继承之后想用就用,不想用允许重写(替换掉)
    public virtual void Eat(string food)
    {
        Console.WriteLine($"{food}");
    }
}

Dog dog = new Dog();

思考:为什么Dog中什么都没声明,但是却能使用Id,和Name这两个属性?

答:因为Dog继承自Animal,所以在使用时可以使用Animal中公开的属性和方法

dog.Id = 3;

dog.Name = "小黄";

//父类公开的方法也可以继承

dog.Eat("骨头");

继承  语法结构子类:父类,类之间支持单继承(单向)

该类的继承链是:Object--->>>Animal--->>>Dog

在C#中最顶级的基类是object,所有的类都继承自Object

 public class Dog:Animal
 {
     public int Age;
     public Dog()
     {
         Console.WriteLine("子类Dog的无参构造函数");
     }
     //推荐的写法
     //base()代表父类的构造函数,加上参数就是访问父类的有参构造函数
     public Dog(int id, string name, int age) : base(id, name)
     {
         this.Age = age;
     }

     //这里需要注意,和父类中公开的被用作继承的方法重名了,会覆盖掉父类中的方法,转而调用自身的

     //override: 重写父类的虚方法,把父类继承过来的Eat替换掉, 名称保留,业务逻辑重写
      public override void Eat(string food)
     {
      Console.WriteLine($"{this.Name}喜欢吃:{food}");
}

如果要使用父类中的方法,不考虑在子类中重写,那么直接调用父类的方法即可.

如果打算在父类的方法上完全推到逻辑重新来整理,又不想换名字,那么可以考虑把父类方法重写,父类方法(virtual),子类使用override

调用带有参数的构造函数时,无参构造函数也会先执行.
            Dog d2 = new Dog(4,"小黑",2);
            //这里的4,和小黑都通过构造函数中的base传递给了父类,让父类构造函数赋值,子类只是纯粹的调用者

你可能感兴趣的:(c#,开发语言)