C# 学习笔记(5) 继承

C# 学习笔记(5) 继承

我们可能会在一些类中,写一些重复的成员,继承就是为了避免重复写这些成员,将这些成员
单独的封装到一个类中,作为这些类的父类。一个类在需要这些重复的成员时,直接继承父类,这些重复的成员就可以省去不写。

单根性

一个子类只能有一个父类, object是所有类的老祖先。

传递性

父类可以传递给子类什么?

  • 父类会将自己的属性和方法传递给子类,但是私有字段不会传递给子类。

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

  • 子类不会继承父类的构造函数,但是在创建子类时会默认先调用父类的无参构造函数创建一个父类对象,然后再调用子类的构造函数,也就是说子类中其实包含了一个父类,所以表面上子类会有父类的公共属性和方法,而父类的私有字段则因为访问权限问题子类访问不到。
    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();
            student.Eat();
            Console.ReadKey();
        }
    }
    public class Person
    {
        public string Name;
        public int Age;
        public bool Gender;
        public Person()
        {
            Console.WriteLine("人类构造函数");
        }

        public void Eat()
        {
            Console.WriteLine("父类吃饭吃两碗");
        }
    }
    class Student : Person
    {
        public Student()
        {
            Console.WriteLine("子类构造函数");
        }
    }
  • 上面代码会输出:

      人类构造函数
      子类构造函数
      父类吃饭吃两碗
    
  • 由于子类会默认调用父类的无参构造函数,如果自己在父类中写了带参的构造函数最好在写一个无参的构造函数方便子类调用(如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,子类就调用不到了,所以子类会报错。)

  • 如果想要子类的构造函数调用父类特定的构造函数需要使用关键字:base()

如果类中的构造函数想调用类中另一个构造函数,需要使用关键字:this()

    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();
            student.Eat();
            Console.ReadKey();
        }
    }
    public class Person
    {
        public string Name;
        public int Age;
        public bool Gender;
        public Person()
        {
            Console.WriteLine("人类构造函数");
        }
        public Person(int age)
        {
            this.Age = age;
            Console.WriteLine("人类构造函数 人类年纪:{0}", this.Age);
        }
        public void Eat()
        {
            Console.WriteLine("父类吃饭吃两碗");
        }
    }
    class Student : Person
    {
        public Student():base(50)
        {
            Console.WriteLine("子类构造函数");
        }
    }
  • 上面代码会输出:

      人类构造函数 人类年纪:50
      子类构造函数
      父类吃饭吃两碗
    

子类中的属性或者方法和父类中的重名会怎么样?

一般来说是禁止子类与父类中的属性与方法重名的,重名时编译器会提示警告,但是可以在子类重名的属性或者方法前添加new关键字,这样子类的属性或者方法就会屏蔽掉父类的重名属性或者方法,这时候如果想调用被屏蔽掉的父类属性或方法,需要使用关键字base. 调用

    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();
            student.Eat();
            Console.ReadKey();
        }
    }


    public class Person
    {
        public string Name;
        public int Age;
        public bool Gender;
        
        public Person()
        {
            Console.WriteLine("人类构造函数");
        }
        public Person(int age)
        {
            this.Age = age;
            Console.WriteLine("人类构造函数 人类年纪:{0}", this.Age);
        }
        public void Eat()
        {
            Console.WriteLine("父类吃饭吃两碗");
        }
    }

    class Student : Person
    {
        public Student():base(50)
        {
            Console.WriteLine("子类构造函数");
        }
        public new void Eat()
        {
            Console.WriteLine("子类吃饭吃两碗");
        }
    }
  • 上面代码会输出:

      人类构造函数 人类年纪:50
      子类构造函数
      子类吃饭吃两碗
    

里氏转换

1)、子类可以赋值给父类
2)、如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象。

里氏替换原则

子类可以扩展父类的功能,但不能改变父类原有的功能。

为什么子类不要更改父类原有功能?
假如有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时重写了父类A中的方法,而该方法有可能是用来实现P1功能的,重写后P1功能可能发生故障。因此当使用继承时,里氏替换原则要求类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值