C# 继承
继承的语法
a、在儿子类的类名后面 写上一个冒号 再跟上父亲类的名字。
a、在儿子类的类名后面 写上一个冒号 再跟上父亲类的名字。
calss Student:Person 子类:父类
1 class Person 2 { } 3 4 class Student : Person 5 { }
b、Student 类从Person类继承,Student类是Person类的子类。Person类是Student类的父类。
Student 类从Person类派生,Student类是Person类的派生类。Person类是Student类的基类。
子类从父类继承,那么子类就拥有父类的全部成员。
继承的特点
a、单根性:一个类只能有1个父类。但是一个类可以实现多个接口。
b、Object类是所有类的基类。C#中的类都直接的或者间接的从Object类继承。
如果我们写一个类,不为这个类指定父类,那么这个类默认就从object类继承。所以我们才可以在这个类中看到object类的成员。
c、传递性:A类从B类继承,B类从C类继承,那么A类就拥有了B和C的所有的成员。
在创建子类对象的时候,会去调用父类的构造函数。
a、先调用子类的构造函数
b、再调用父类的构造函数
c、再执行父类的构造函数
d、再执行子类的构造函数
调用父类的构造函数为当前对象的子类对象的父类成员赋值
父类的属性放在父类的构造函数中初始化。而子类对象中拥有自己的属性和从父类继承过来的属性,我们要为子类写一个构造函数,用于初始化子类的所有属性,
a、直接写一个子类构造函数会去调用父类的无参数的构造函数。所以父类如果如果无参数的构造函数的话,要为父类添加一个。
b、将父类的属性的值交给父类的构造函数去初始化。子类构造函数只初始化自己的属性。此时,如果子类构造函数调用父类的构造函数,在父类的构造函数中访问的成员不是父类对象的,是当前子类对象中的父类成员
补充
1、结构体是不能够继承的,但是可以实现接口。
但是所有的结构体都默认从ValueType这个类继承。而ValueType这个类又从Object继承,根据继承的传递性,所以我们的结构体对象中就拥有Object类的成员。
2、子类的访问级别不能比父类高
3、静态类是不能被继承的
a、静态类不能相互继承,因为静态类没有实例构造函数
b、静态类默认直接从Object去继承
c、静态类的本质其实是一个密封类。
4、在子类中可以存在和父类中的同名方法,如果方法的参数的个数或者类型不同,那么他们子类中构成重载。
5、在子类对象中是可以存在和父类相同的成员。
- 创建父类对象,通过父类对象调用这个同名成员,毫无疑问调用的是父类的。
- 创建子类对象,通过子类对象调用这个同名成员,调用的是子类自己独有的。
- 子类中的同名成员会将父类的同名成员覆盖掉,所以我们通过子类对象来调用同名成员的时候,它调用的是子类的同名成员。
- 请记住,通过子类对象是无论如何也调用不到同名的父类成员,因为子类的同名成员将父类的同名成员覆盖掉了。但是在子类的内部,仍然是可以通过base关键字调用到父类的同名成员。
问题
Q1:子类从父类继承,子类就可以拥有父类的全部成员吗?
a、在子类中,可以访问父类的public 和internal 不能访问private。
b、子类从父类继承,那么子类模版中就拥有了父类模版中的所有成员,包括私有成员。在创建子类对象的时候,因为子类对象是根据子类模版创建的,所以子类对象当中自然也就有父类的私有成员。只不过父类的私有成员,在子类的内部无法访问,但是它却真实的存在。
c、类的成员的访问修饰符
public:可以在任意地方访问
private:只能在类的内部访问
internal:可以在当前程序集访问
protected:可以在本类的和本类的子类中访问。
d、子类从父类继承,子类模版中就拥有了父类模版中的所有成员,包括私有的。只不过在子类的内部只能访问父类的 非私有成员。
Q2:为什么创建子类对象的时候要去调用父类的构造函数呢?
因为父类的字段的初始化是放在父类的构造函数中。如果创建子类对象的时候不去调用父类的构造函数,那么创建完这个子类对象以后,这个子类对象中从父类继承过来的字段就没有默认值。
默认情况下,子类的构造函数会去调用父类的无参数的构造函数。但是如果父类没有无参数的构造函数,那么我们要通过base关键字为子类构造函数指定要调用父类的哪一个构造函数。
语法:
public 子类():base()
{}
在base的小括弧中通过实参的个数和类型去匹配父类的构造函数。