约瑟夫·阿尔巴哈里和本·阿尔巴哈里(奥莱利)在果壳中的C#6.0。版权所有2016 Joseph Albahari和Ben Albahari,978-1-491-92706-9。
在引入隐式调用无参数基类构造函数之后,在第96页说明如下:
如果基类没有可访问的无参数构造函数,则子类被强制在其构造函数中使用
base
关键字。
我正在尝试创建一个代码段来证实这一点,但还没有成功。
我的片段:
public class X
{
public int Num { get; set; }
public void Method_1()
{
Console.WriteLine("X");
}
public virtual void Method_2()
{
Console.WriteLine(Num);
}
}
public class Y : X
{
public Y()
{
Num = 1000;
}
}
private static void Main(string[] args)
{
new Y().Method_2();
}
我希望在书肯定之后得到编译器错误,但我没有得到。代码运行并正确打印1000。
我的问题是:本书对于子类被强制使用基本关键字意味着什么?我正在尝试重现这种情况。
我错过了什么?
答案 0 :(得分:10)
类Y
可以访问基类X
的无参数构造函数,因为如果类没有定义构造函数,则存在隐式无参数构造函数。< / p>
如果你写:
public class X
{
public X(int i){}
}
然后X
中将不再有Y
的无辅助参数构造函数。
答案 1 :(得分:5)
问题源于您对示例代码的误解。因为你没有在class X
中定义任何构造函数,所以C#为你定义了一个隐含的构造函数。这个隐式构造函数是一个无参数的构造函数。
您提到的引用是指您实际编写非默认构造函数的情况。
编写非默认构造函数会抑制隐式构造函数的生成。这意味着您必须使用Dervived
关键字从base
类的构造函数显式调用另一个构造函数
class BaseClass
{
public BaseClass(int i) {}
}
class Derived : BaseClass
{
public Derived() : base(44) { }
}
答案 2 :(得分:0)
规则相同,但......
这实际上与访问基类的任何其他成员的常规规则没有什么不同。
构造函数只不过是常规函数。
关键区别在于派生类会自动尝试调用基础构造函数。特别是没有参数的基础构造函数。
如果不存在构造函数,则会出现错误。如果它存在,但您没有&#34;权限&#34;要访问它,就会出错。
如果你没有为基类指定任何构造函数,则假定该类具有无参数的构造函数。
换句话说,如果你没有指定一个构造函数,那么就是为你隐式创建的。
以下是7个您何时会遇到此问题的例子:
示例3 - 确定 - 隐含的默认空构造函数
class Base
{
// No constructor explicitly defined so a default constructor is assumed
// Having no constructor at all is like having an empty constructor
// Like this: Base() { }
}
class Derived : Base
{
// OK - Explicitly calling accessible base constructor
public Derived() { }
}
示例2 - 确定 - 可访问的基础构造函数
class Base {
// "public" so it's accessible by derived class
public Base() { } // no parameters - aka parameterless
}
class Derived : Base {
// OK - implicitly calls accessible parameterless constructor base()
public Derived() {}
}
示例3 - 确定 - 受保护的方式仍可访问
class Base {
// "protected" so it's accessible by derived class
protected Base() { } // no parameters - aka parameterless
}
class Derived : Base {
// OK - implicitly calls accessible parameterless constructor base()
public Derived() {}
}
示例4 - 失败 - 私人无法访问
class Base {
// "private" so it's NOT accessible by derived class
private Base() { } // no parameters - aka parameterless
}
class Derived : Base {
// FAIL - tries to implicitly call parameterless constructor base()
// ERROR CS0122 - Base.Base() is inaccessible due to it's protection level
public Derived() { }
}
示例5 - 失败 - 始终尝试调用无参数构造函数
class Base {
// "private" so it's NOT accessible by derived class
private Base() { } // no parameters - aka parameterless
// "protected" so it's accessible by derived class
protected Base(int a) { } // has parameter - aka NOT parameterless
}
class Derived : Base {
// FAIL - STILL tries to implicitly call parameterless constructor base()
// ERROR CS0122 - Base.Base() is inaccessible due to it's protection level
public Derived() { }
}
示例6 - 失败 - 除非它不存在,否则假设调用另一个
class Base
{
// notice there is not parameterless constructor
// just one constructor does does have parameters
// "protected" so it's accessible by derived class
protected Base(int a) { } // has parameter - aka NOT parameterless
}
class Derived : Base
{
// FAIL - STILL tries to implicitly call parameterless constructor base() which doesn't exist
// ERROR CS7036 - There is no argument given that corresponds to the required formal parameter 'a' of Base.Base(int)
public Derived() { }
}
示例7 - 确定 - 除非您自己打电话
class Base
{
// "private" so it's NOT accessible by derived class
private Base() { } // no parameters - aka parameterless
// "protected" so it's accessible by derived class
protected Base(int a) { } // has parameter - aka NOT parameterless
}
class Derived : Base
{
// OK - Explicitly calling accessible base constructor with `int` parameter
public Derived()
: base(10)
{ }
}