静态成员与静态类
静态成员通过static关键字来标识,可以是静态方法、字段、属性或事件。
与非静态成员的区别:静态成员属于类,而不属于类的实例,需要通过类而不是通过类的实例来访问;非静态成员的区别则总是与特定的实例(对象)相联系。
注:
- 静态成员属于类,只能通过类名引用。C#中表示当前实力的关键字this不能在静态方法中使用。
- 静态数据成员在所有对象之外单独开辟空间。
- 非静态方法(实例方法)中可直接访问实例成员和实例方法,也可直接访问静态成员和静态方法。但静态方法中只能访问静态成员。
静态构造函数不是为了创建对象而设计的,而是
用来初始化类,只有非静态的构造函数才用来创建对象(用于创建对象的构造函数称为实例函数)。由于静态构造函数并不对类的特定实例进行操作,所以也称为全局或共享构造函数。
在C#应用程序中,不能直接调用静态构造函数。静态构造函数在类的第一个实例创建之前或调用类的任何静态方法之前执行,而且最多执行一次,适合对类的静态成员进行初始化。
静态构造函数可以与实力构造函数共存。静态构造函数名与类名相同,声明时不能带访问修饰符,并且不能有任何参数和返回值。
静态类不能使用new关键字创建静态类的实例。在实际应用中,当类中的成员不与特定对象关联的时候,就可以把它创建为静态类。
特点:
- 仅包括静态成员。
- 不能实例化。
- 密封的,不能被继承。
- 不能包含实例构造函数,但仍可以声明静态构造函数,以分配初始值或设置某个静态状态。
特点:
- 编译器能够自动执行检查,以确保不添加实例成员;
- 静态类能够使程序的实现更简单、迅速,因为不必创建对象就能调用方法。
类的继承性与多态性
C#允许创建一个通用类(基类/父类),然后从通用类派生出更多的特殊类(派生类/子类)。
继承性只需对添加的成员进行定义,使已有的程序设计具有了可扩展性,既提高了代码的重用性,又提高了程序设计的效率。类的继承性为面向对象程序设计构建一个分层类结构体系创造了条件,而.NET框架类库就是一个庞大的分层类结构体系。其中Object类是一个最上层的基类。
继承的原则:
- 派生类只能从一个类中继承,即单继承。
- 派生类自然继承基类的成员,但不能继承基类的构造函数。
- 类的继承可以传递。
1.派生类的声明
public:可以在派生类中访问,也允许其他类访问。
protected:由所属类或派生类的成员访问,可既保证不能在类定义外直接访问成员,又允许其派生类访问成员。
private:只能有所属类的成员才能访问。
2.构造函数的调用
C#中,派生类不能继承其基类的构造函数,但在创建对象时,允许调用构造函数,为对象分配内存,并初始化对象的数据。创建派生类对象时,为了完成其基类部分的成员初始化,允许调用基类的构造函数。其构造函数的调用顺序是先调用基类构造函数,再调用派生类的构造函数,以完成数据成员分配内存空间并进行初始化的工作。
public class Student //基类
{
……
public Student() //基类的构造函数
{
this.name = "无名";
this.age = 0;
}
……
}
public class Undergraduate : Student //派生类
{ …… }
若把基类的构造函数改为:
public Student(string name,int age) //基类的构造函数 { this.name = name; this.age = age; }
编译会报错“Student不包含采用0个参数的构造函数”。因为当创建派生类对象时,系统默认调用基类的默认构造函数(即无参构造函数),而当基类没有默认构造函数或想调用基类的带参数的构造函数,需要用base关键字。
public class Student //基类
{
……
public Student(string name,int age) //基类的构造函数 { this.name = name; this.age = age; }
……
}
public class Undergraduate : Student //派生类
{
……
public Undergraduate():base(“无名”,0) //派生类的默认构造函数
{subject=“未知”;}
public Undergraduate(string name,int age,string subject):base(name,age) //派生类的带参造函数
{this.subject=subject;}
……
}
3.密封类
为了阻止一个类的代码被其他类继承,可以使用密封类,可以提高应用程序的可靠性和性能。声明类时添加关键字sealed。
派生类允许扩展基类的成员,也可以重写基类的方法成员,以更改基类的数据和行为。为了使用派生类能更改基类的数据和行为,C#提供了两种选择:一是使用新的派生成员替换基成员,二是重写虚拟的基成员。
1.使用new关键字重新定义类的成员
使用new关键字来定义与基类中同名的成员,即可替换基类的成员。new关键字应放置在要替换的类成员的数据类型之前。
2.用virtual和override关键字定义类成员