构造函数
构造函数的执行顺序是先执行基类的构造函数,在执行子类的构造函数。这样子类的构造函数中就可以调用积累的方法、属性、成员。基类的构造函数如果声明为private,子类将无法构造。
如果提供了带参数的构造函数,编译器就不会自动提供默认的构造函数.只有没有定义任何构造函数的情况下,编译器才提供默认的构造函数。如果提供了带有参数的构造函数,编译器会认为这是唯一的构造函数,不会隐式的提供其他构造函数。
静态构造函数:目的是类有一些静态字段或属性,需要在第一次使用类之前初始化。
- 无参数;
- 在代码引用类以前只执行一次,通常在第一次调用能够类的成员之前执行;
- 没有确定的执行机会,无顺序。
- 其他c#代码不访问静态构造函数,.NET运行库调用它。所以public或protect无意义。
- 一个类只能有一个静态构造函数
- 静态函数只能访问范文静态成员,不能访问实例成员。
this 仅调用能够参数最匹配的那个构造函数。
只读字段
其值不应改变,但在运行前值是未知的。可以经过一些运算确定只读字段的值。只能在构造函数中给只读字段赋值。
只读字段可以不是静态字段,而是实例字段,做这样类的每个实例可以有不同的值。如果要把只读字段设置为静态就必须显示声明。不需要把只读字段设置为私有,因为按照定义他们不能在外部修改。
结构
struct route
{
public orientation dir;
public double distance;
}
结构不支持实现继承,但可以继承接口。
编译器总为结构提供一个无参数的默认构造函数,不允许替换。
结构声明后可以直接调用数据成员初始化而不需要new。结构作为参数时,考虑使用ref,避免性能损失。
结构继承与System.ValueType,System.ValueType继承与System.Object,所以结构可以访问System.Object的方法。
New&override
new关键字跟继承没有关系,可以用在一个类的子类。当子类的一个方法用到new(这个方法可以和基类的一个方法同名,也可以不同),调用的时候会运行基类的同名方法,而不会调用子类有new关键字的方法;override只是在继承的时候才会用到,用在子类要覆盖基类方法的方法。当一个子类的方法用到override 关键字,在调用的时候会运行子类中相应的方法。
如果你用override,则无论调用的是A类还是B类中的TEST(),系统都会找到它实质类的TEST();
如果是用的New,则可以通过类型转换调用到基类的TEST();
简而言之 New 看等号左边,override看等号右边.
下面是override的情况:
A a = new A();
B b = new B();
A a1=new B();
a.Test();//调用A中Test();
b.Test();//调用B中Test();
a1.Test();//调用B中Test();系统会自动识别a1是B的实例
((A)b).Test();//与上面相同
下面是new的情况:
A a = new A();
B b = new B();
A a1=new B();
a.Test();//调用A中Test();
b.Test();//调用B中Test();
a1.Test();//调用A中Test();
((A)b).Test();//与上面相同
再一个例子
public class ParentClass//基类
{
public ParentClass()
{
Console.WriteLine("在基类的构造方法");
}
public virtual void Method()//用virtual才可以在子类中用override,而new不需要这样
{
Console.WriteLine("基类的方法Method()");
}
}
public class ChildClass1 : ParentClass//继承基类,看看override状态
{
public ChildClass1()
{
Console.WriteLine("ChildClass1的构造方法");
}
public override void Method()//使用override,是说把基类的方法重新定义
{
Console.WriteLine("ChildClass1的方法Method() use override");
}
}
public class ChildClass2 : ParentClass//继承基类,看看new状态
{
public ChildClass2()
{
Console.WriteLine("ChildClass2的构造方法");
}
new public void Method()//使用new,不是说用到基类的方法,而是重新定义一个子类方法,只不过,方法名称与基类相同
{
Console.WriteLine("ChildClass2的方法Method()");
}
}
public class Test
{
static void Main()
{
ParentClass Parent = (ParentClass)new ChildClass1();//用override子类加框一个基类对象句柄
Parent.Method();
ParentClass NewParent = (ParentClass)new ChildClass2();//用new子类加框一个基类对象句柄
NewParent.Method();
ChildClass2 NewParent1 = new ChildClass2();//一个子类句柄
NewParent1.Method();
}
}
运行结果:
在基类的构造方法
ChildClass1的构造方法
ChildClass1的方法Method() use override
在基类的构造方法
ChildClass2的构造方法//表现出继承的特性
基类的方法Method()
在基类的构造方法 //表现出继承的特性
ChildClass2的构造方法
ChildClass2的方法Method()
继承
成员字段和静态函数不能声明为virtual,因为这个概念只针对类的实例函数成员有意义。抽象函数不需要使用virtual声明。
如果有类型嵌套,内部的类型总是可以访问外部类型的所有成员。