10.6 在派生类中指定基类构造函数

我们刚讲过了类的初始化顺序,在类初始化的第二个阶段,就是调用基类的构造函数的阶段,默认调用的是基类的无参数的构造函数,因为构造函数可以重载,基类除了具有无参数的构造函数外,可能还有其他带参数的构造函数。因此,如果我们要指定某一个基类的构造函数,而不是无参数的构造函数,那么就必须在构造函数初始化语句中进行显式指定。

方法有两种:

❑使用base关键字,指定基类的某个构造函数;

❑使用this关键字,指定使用当前类的某个构造函数。

我们先来看看如何在派生类中显式指定其基类的某个构造函数,语法如下:


class SomeClass:BaseClass

{

public SomeClass()

:base()

{

}

public SomeClass(string str)

:base(str)

{

}

}


我们通过一个实例,来看看如何通过base关键字指定基类的某个构造函数。如代码清单10-7所示。

代码清单10-7 使用base关键字指定基类构造函数


1 using System;

2

3 namespace ProgrammingCSharp4

4{

5 class BaseClass

6

{

7 public string FieldA=“我在基类中”;

8 public BaseClass()

9{

10 Console.WriteLine(“基类的构造函数”);

11}

12

13 public BaseClass(string str)

14{

15 Console.WriteLine(“基类的构造函数,参数:{0}”,str);

16}

17}

18

19 class ChildClass:BaseClass

20{

21//隐藏了基类中的FieldA成员

22 new public string FieldA=“我在派生类中”;

23 public ChildClass()

24:base()

25{

26 Console.WriteLine(“派生类的构造函数”);

27}

28

29 public ChildClass(string str)

30:base(str)

31{

32 Console.WriteLine(“派生类的构造函数,参数:{0}”,str);

33}

34

35 public void Print()

36{

37 Console.WriteLine(FieldA);

38 Console.WriteLine(base.FieldA);

39}

40}

41

42 class ClassExample

43{

44 public static void Main()

45{

46 ChildClass child=new ChildClass("a");

47 child.Print();

48}

49}

50}


上述代码运行结果如下:


基类的构造函数,参数:a

派生类的构造函数,参数:a

我在派生类中

我在基类中


如果我们将第30行注释掉,亦即不指定基类带参数的构造函数BaseClass(string str),那么运行结果如下:


基类的构造函数

派生类的构造函数,参数:a

我在派生类中

我在基类中


可见,虽然我们使用的派生类带参数的构造函数对派生类进行实例化,但默认情况下调用的仍是基类不带参数的构造函数。

接下来,我们使用第二种方法,看看如何显式指定使用当前类的某个构造函数,语法如下:


class SomeClass:BaseClass

{

public SomeClass()

:this("something")

{

}

public SomeClass(string str)

{

}

}


我们继续看看如何使用上述方式来显式指定当前类的某个构造函数,如代码清单10-8所示。

代码清单10-8 使用this关键字指定当前类构造函数


1 using System;

2

3 namespace ProgrammingCSharp4

4{

5 class BaseClass

6{

7 public BaseClass()

8{

9 Console.WriteLine(“基类的构造函数”);

10}

11

12 public BaseClass(string str)

13{

14 Console.WriteLine(“基类的构造函数,参数:{0}”,str);

15}

16}

17

18 class SomeClass:BaseClass

19{

20 public SomeClass()

21:this("something")

22{

23 Console.WriteLine(“调用SomeClass()构造函数”);

24}

25

26 public SomeClass(string str)

27:this(str,10)

28{

29 Console.WriteLine(“调用SomeClass(string str)构造函数”);

30}

31

32 public SomeClass(string str,int val)

33{

34 Console.WriteLine(“调用SomeClass(string str,int val)构造函数”);

35}

36}

37

38 class ClassExample

39{

40 public static void Main()

41{

42 SomeClass someClass=new SomeClass("something");

43}

44}

45}


上述代码运行结果如下:


基类的构造函数

调用SomeClass(string str,int val)构造函数

调用SomeClass(string str)构造函数


对代码清单10-8的说明如表10-6所示。

10.6 在派生类中指定基类构造函数 - 图1

从上述运行结果来看,虽然我们初始化类的时候使用的是SomeClass(string str)构造函数,因此会先调用SomeClass(string str,int val)构造函数,其次才是SomeClass(string str)构造函数。