继承是面向对象编程最基本的点,那么你是否真的理解c#子类与父类之间的继承关系,特别是是构造函数的继承关系。很多时候我们似乎经常在用继承,但是我们却没有真正注意到继承关系中父类与子类之间的关系。 下面我们先给出一个例子:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { MyClass3 my = new MyClass3(3, 4); Console.WriteLine(); } } public class MyClass { public MyClass() { Console.WriteLine("MyClass:默认构造函数"); } public MyClass(int a, int b) { Console.WriteLine("MyClass带参构造:a={0}, b={1}.", a, b); } } public class MyClass2 : MyClass { public MyClass2() { Console.WriteLine("MyClass2:默认构造函数"); } public MyClass2(int a, int b) { Console.WriteLine("MyClass2带参构造:a={0}, b={1}.", a, b); } } //C#继承构造函数实现及调用 public class MyClass3 : MyClass2 { public MyClass3() { Console.WriteLine("MyClass3:默认构造函数"); } public MyClass3(int a, int b) { Console.WriteLine("MyClass3带参构造:a={0}, b={1}.", a, b); } } }
你认为输出的答案是什么?给你三个选择
答案是:D,你选对了吗?
为什么呢?
原因就是所有的类都是按照继承链从顶层基类开始向下顺序构造,子类无论是默认构造(无参构造)和带参构造都默认将从顶层父类的默认构造一直调用到当前类之前的默认构造,当前类的构造函数。
但是我们可以在构造函数语句之前使用 :base(参数) 来指定当前类调用上层类的哪一个构造函数。
例如下面的例子:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 构造函数继承 { //1.构造函数继承的时候,先调用基类的构造函数方法,再调用自己的构造函数方法 //2.子类构造函数可以继承父类不同参数个数的构造函数 class Class1 { public Class1(string a, string b) { Console.WriteLine("Class1 2个参数的构造函数,a={0},b={1}", a, b); } } class Class2 : Class1 { public Class2() : base("class2_a", "class2_b") { Console.WriteLine("Class2无参构造函数 继承自Class1的被调用"); } } class Test { static void Main(string[] args) { Class2 class2 = new Class2(); Console.ReadKey(); } } }
输出的答案是:
Class1 2个参数的构造函数,a=class2_a,b=class2_b Class2无参构造函数 继承自Class1的被调用