定义类

来源:互联网 发布:郑州金蝶软件 编辑:程序博客网 时间:2024/05/18 01:09

一、定义类注意事项:

1.1默认情况下,类声明为内部的,即只有当前项目中的代码才能访问它。可以使用internal 访问修饰符关键字显式指定,如下所示(但这是不必要的):

internal class MyClass

{

// Class members.

}

另外,还可以指定类是公共的,应该可以由其他项目中的代码来访问。为此,要使用关键字public。

public class MyClass

{

// Class members.

}

1.2除了这两个访问修饰符关键字外,还可以指定类是抽象的(不能实例化,只能继承,可以有抽象成员)或密封的(sealed,不能继承)。为此,可以使用两个互斥的关键字abstract 或sealed。

1.3注意,在C#的类定义中,只能有一个基类,如果继承了一个抽象类,就必须实现所继承的所有抽象成员(除非派生类也是抽象的)。

1.4编译器不允许派生类的可访问性高于基类。也就是说,内部类(internal)可以继承于一个公共基类,但公共类不能继承于一个内部类。

1.5所有接口成员都必须在支持该接口的类中实现,但如果不想使用给定的接口成员,就可以提供一个“空”的实现方式(没有函数代码)。还可以把接口成员实现为抽象类中的抽象成员。

二、System.Object:

因为所有的类都继承于System.Object,所以这些类都可以访问该类中受保护的成员和公共的成员。

(具体的成员可以参考官方文档,这里列一些常用的。)

Object()方法:System.Object 类型的构造函数,由派生类型的构造函数自动调用。

~Object()方法:System.Object 类型的析构函数,由派生类型的析构函数自动调用,不能手动调用。

Equals(object)方法:返回bool类型;把调用该方法的对象与另一个对象相比,如果它们相等,就返回true。默认的实现代码会查看对象的参数是否引用了同一个对象(因为对象是引用类型)。如果想以不同的方式来比较对象,则可以重写该方法,例如,比较两个对象的状态。

ToString()方法:返回string类型;返回一个对应于实例的字符串。默认情况下,这是一个类类型的限定名称,但可以重写它,给类型提供合适的实现方式。

GetType()方法:返回system.Type类型;以System.Type 对象的形式返回对象的类型。

在利用多态性时,GetType()是一个有用的方法,允许根据对象的类型来执行不同的操作,而不是像通常那样,对所有的对象都执行相同的操作。

联合使用GetType()和typeof(这是一个C#运算符,可以把类名转换为System.Type 对象),就可以进行比较,如下所示:

if (myObj.GetType() == typeof(MyComplexClass))

{

// myObj is an instance of the class MyComplexClass.

}

三、构造函数的执行序列:

为了实例化派生的类,必须实例化它的基类。而要实例化这个基类,又必须实例化这个基类的基类,这样一直到实例化System.Object(所有类的根)为止。结果是无论使用什么构造函数实例化一个类,总是要先调用System.Object.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()构造函数。

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)构造函数。

使用这个顺序可以把使用int i 参数的代码放在MyBaseClass(int i)中,即MyDerivedClass(int i, intj)构造函数要做的工作比较少,只需要处理int j 参数(假定int i 参数在两种情况下含义相同,虽然事情并非总是如此,但实际上我们常常做这样的安排)。只要愿意,C#就可以指定这种操作。为此,只需使用构造函数初始化器,它把代码放在方法定义的冒号后面。例如,可以在派生类的构造函数定义中指定所使用的基类构造函数,如下所示:

public class MyDerivedClass : MyBaseClass

{

...

public MyDerivedClass(int i, int j) : base(i)

{

}

}

其中,base 关键字指定.NET 实例化过程使用基类中有指定参数的构造函数。这里使用了一个int参数(其值通过参数i 传送给MyDerivedClass 构造函数),所以应使用MyBaseClass(int i)。这么做将不调用MyBaseClass(),而是执行本例前面列出的事件序列——也就是我们希望执行的事件序列。

也可以使用这个关键字指定基类构造函数的字面值,例如,使用MyDerivedClass 的默认构造函数调用MyBaseClass 非默认的构造函数:

public class MyDerivedClass : MyBaseClass

{

public MyDerivedClass() : base(5)

{

}

...

}

MyDerivedClass myObj = new MyDerivedClass();

这段代码将执行下述序列:

1)执行 System.Object.Object 构造函数。

2)执行MyBaseClass.MyBaseClass(int i)构造函数。

3)执行 MyDerivedClass.MyDerivedClass()构造函数。

除了base 关键字外,这里还可以将另一个关键字this 用作构造函数初始化器。这个关键字指定在调用指定的构造函数前,.NET 实例化过程对当前类使用非默认的构造函数。例如;

public class MyDerivedClass : MyBaseClass

{

public MyDerivedClass() : this(5, 6)

{

}

...

public MyDerivedClass(int i, int j) : base(i)

{

}

}

MyDerivedClass myObj = new MyDerivedClass();

这段代码将执行下述序列:

1)执行 System.Object.Object 构造函数。

2)执行MyBaseClass.MyBaseClass(int i)构造函数。

3)执行MyDerivedClass.MyDerivedClass(int i, int j)构造函数。

4)执行 MyDerivedClass.MyDerivedClass()构造函数。

注意:如果没有给构造函数指定构造函数初始化器,编译器就会自动添加base()

原创粉丝点击