任何构造函数都可以进行配置,以便在执行自己的代码前调用其它构造函数。
我们首先看看在创建类的实例时会发生什么情况。为了实例化派生的类,必须实例化它的基类。而要实例化这个基类,又必须实例化这个基类的基类,这样一直实例化到System.Object为止。结果是无论使用什么构造函数实例化一个类,总是要先调用System.Object.Object()。
如果对一个类使用非默认的构造函数,默认的情况是在其基类上使用匹配于这个构造函数签名的构造函数。如果没有找到这样的构造函数,就使用基类的默认构造函数(根类System.Object总是要使用默认的构造函数,因为这个类没有非默认的构造函数)。
我们以下面这个小代码段例子作一些说明:
public class MyBaseClass
{
public MyBaseClass()
{
}
public MyBaseClass(int i)
{
}
}
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass()
{
}
public MyDerivedClass(int i)
{
}
public MyDerivedClass(int i, int j)
{
}
}
如果以下面的方式实例化MyDerivedClass:
MyDerivedClass myObj = new MyDerivedClass();
则发生下面的一系列事件:
1.执行System.Object.Object()构造函数。
2.执行MyBaseClass.MyBaseClass()构造函数。
3.执行MyDerivedClass.MyDerivedClass()构造函数。
如果使用下面的语句:
MyDerivedClass myObj = new MyDerivedClass(4);
则发生下面的—系列事件:
1.执行System.Object.Object()构造函数。
2.执行MyBaseClass.MyBaseClass(int i)构造函数。
3.执行MyDerivedClass.MyDerivedClass(int i)构造函数。
如果使用下面的语句:
MyDerivedClass myObj = new MyDerivedClass(4,8);
则发生下面的—系列事件:
1.执行System.Object.Object()构造函数。
2.执行MyBaseClass.MyBaseClass()构造函数。
3.执行MyDerivedClass.MyDerivedClass(int i, int j)构造函数。
有时需要对发生的事件进行更多的控制。例如,在上面的实例化范例中,需要有下面的事件序列:
1.执行System.Object.Object()构造函数。
2.执行MyBaseClass.MyBaseClass(int i)构造函数。
3.执行MyDerivedClass.MyDerivedClass(int i, int j)构造函数。
使用这个序列可以在编写MyBaseClass(int i)中使用int i参数的代码,即MyDerivedClass(int i, int j)构造函数要做的工作比较少,只需要处理int j参数(假定int i参数在两种情况下有相同的含义)。我们仅需指定在派生类的构造函数定义中所使用的基类的构造函数,如下所示:
public class MyDerivedClass : MyBaseClass
{
……
public MyDerivedClass(int i, int j) : base(i)
{
}
}
其中,base关键字指定.NET实例化过程,以使用基类中匹配指定签名的构造函数。这个例子中使用一个int参数,所以在实例化序列中应调用MyBaseClass(int i)。
同时我们也可以使用这个关键字指定基类构造函数的字面值。
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass() : base(5)
{
}
……
}
这段代码将执行以下序列:
1.执行System.Object.Object()构造函数。
2.执行MyBaseClass.MyBaseClass(int i)构造函数。
3.执行MyDerivedClass.MyDerivedClass()构造函数。
下面我们介绍另一个关键字this。这个关键字指定在调用指定的构造函数前,.NET实例化过程对当前类使用非默认的构造函数。
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass() : this(5,6)
{
}
……
public MyDerivedClass(int i, int j) : base(i)
{
}
}
这段代码将执行以下序列:
1.执行System.Object.Object()构造函数。
2.执行MyBaseClass.MyBaseClass(int i)构造函数。
3.执行MyDerivedClass.MyDerivedClass(int i,int j)构造函数。
4.执行MyDerivedClass.MyDerivedClass()构造函数。
唯一的限制是使用this或base关键字只能指定一个构造函数。但是如上所示,这并不是一个很严厉的限制,按照上述方式仍可以构造相当复杂的执行序列。
分享到:
相关推荐
c#学习笔记(1) 51099在线学习网发布 文章来源:网络收集 发布时间:2006-05-25 字体: [大 中 小] 51099在线学习网 http://www.51099.com 1, 结构(struct) 与 类(class) [attributes] [modifiers] struct ...
- **构造函数**:用于初始化新创建的对象。 - **访问修饰符**:如`public`、`private`、`protected`和`internal`,控制成员的可见性。 - **继承**:子类可以继承父类的属性和方法。 - **多态**:通过接口和虚...
- **转换函数**:通过定义转换构造函数或转换运算符实现类型之间的转换。 - **装箱(Boxing)和拆箱(Unboxing)**:在值类型和引用类型之间进行转换。 #### 三、运算符与程序流程 **3.1 运算符** - **new操作符**:...
抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。 41.构造器Constructor是否可被override? 答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被...
- **面向对象编程**:类和对象的概念,构造函数,继承,接口,抽象类,封装,多态。 - **集合与泛型**:了解集合框架,掌握泛型编程,提高代码的复用性和安全性。 - **异常处理**:学习如何使用try-catch-finally...
02_构造函数的执行序列.htm.txt 03_抽象类和接口.htm.txt 04_结构类型.htm.txt 05_类成员的定义.htm.txt 06_类成员的其他议题.htm.txt 07_接口的执行.htm.txt 08_集合.htm.txt 09_运算符重载.htm.txt 10_...
本篇学习笔记主要聚焦于Xamarin中的Android平台,探讨了如何利用Parcel和IParcelable接口来实现对象的序列化和反序列化,以便在不同的组件或进程中传递数据。 Parcel是Android系统提供的一种轻量级的数据存储和传输...
### Java学习笔记整理 #### 1. Java简介 ##### 1.1 计算机编程和开发语言 计算机系统由硬件系统和软件系统组成。软件系统又进一步细分为系统软件和应用软件。其中,系统软件包括操作系统、编译系统、数据库系统等...
02_构造函数的执行序列.htm.txt 03_抽象类和接口.htm.txt 04_结构类型.htm.txt 05_类成员的定义.htm.txt 06_类成员的其他议题.htm.txt 07_接口的执行.htm.txt 08_集合.htm.txt 09_运算符重载.htm.txt 10_...
2. **类与对象**:这是C#中的核心概念,涉及类的定义、对象的创建、属性、方法、构造函数、析构函数以及封装、继承和多态等面向对象特性。 3. **命名空间与引用**:C#通过命名空间来组织代码,理解如何导入和使用...
1. 直接使用FileStream类的构造函数创建流,可以指定文件名、文件打开模式、文件访问权限和文件共享权限。 2. 利用File类或FileInfo类的Open方法来创建流,该方法同样需要上述参数。 3. 使用File类或FileInfo类的...