对象和类型
一、类
类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法。
首先来看c#的类,类包含数据成员和函数成员,类的成员的访问方式:object.member,其中object是类的实例,member是类的成员。
1.1 数据成员
数据成员包含类的数据——字段、常量和事件。字段就是我们通常所说的成员变量,事件可以让对象将某些特定行为发生的时间告知调用的程序。
1.2 函数成员
函数成员提供操作类中数据的功能,包括方法、属性、构造函数和终结器、运算符以及索引器。
1)方法。就是与类相关的函数,有静态方法和非静态方法之分。
方法的声明格式:
方法传递参数:在C#中所有的参数都是通过值来传递的,除非特别声明。(使用ref或者out关键字,
可迫使值参数通过引用来传递参数),例如:
out关键字的时候,传递给方法的参数可以不初始化,但是C#规定必须在方法内部给参数赋值,如果
没有赋值,编译就会出错。
方法的重载:C#在重载方法的参数方面有一些小区别即可:
a)两个方法不能仅在返回类型上有区别
b)两个方法不能仅根据参数是声明为ref还是out来区分
2)属性
属性定义语法:
get不带任何参数,且必须返回为属性声明的类型。set也不带参数,但编译器假定它带一个参数,其
类型也与属性相同,并表示为value。
如果省略set,属性就是只读属性。如果没有get,属性就是只写属性。
3)构造函数
C#中声明基本构造函数的语法与Java和C++中相同。构造函数的重载与其它方法的重载规则相同。
再没有显示定义任何构造函数的时候,编译器会自动提供默认的构造函数,如果提供了构造函数,
编译器就不提供默认构造函数。
a)静态构造函数
C#的一个新特征是可以给类编写无参数的静态构造函数。这种函数只执行一次。
编写静态构造函数的一个原因是,类有些静态字段或属性,需要在第一次使用类之前,从外部源
中初始化这些静态字段和属性。
静态构造函数只能访问静态成员,且没有访问修饰符,没有参数,且一个类也只能有一个静态构造函数。无参数的实例构造函数可以在类中与静态构造函数安全共存。
b)从其它构造函数中调用构造函数
一个类可能包含多个构造函数,它们之间可以相互调用
还可以对直接基类的构造函数进行调用,把this改成base。注意,初始化符中不能有多于一个的调用。且C#初始化符中只能调用另一个构造函数。
3)只读字段(readonly字段)
readonly关键字比const灵活得多,允许把字段设置为常量,但可以执行一些运算,以确定它的初始值。其规则是可以在构造函数中给readonly字段赋值,但不能在其它地方赋值。如果在构造函数中没有赋值,那么它的值就是数据类型的默认值,或者在声明的时候初始化。readonly字段还可以是实例字段,而不是静态字段。
二、结构
结构的定义与类完全相同。
三、类和结构的区别
区别在以下几个方面:
1.数据类型不同。类是引用类型,存储在托管堆中;结构是值类型,存储在堆栈中。
2.访问方式不同。
3.结构不支持继承。
4.结构的构造函数的工作方式与类有些不同。尤其是编译器总是给类提供一个无参数的默认构造函数,这是不允许替换的。
5.使用结构,可以指定字段如何在内存中布局
类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法。
首先来看c#的类,类包含数据成员和函数成员,类的成员的访问方式:object.member,其中object是类的实例,member是类的成员。
1.1 数据成员
数据成员包含类的数据——字段、常量和事件。字段就是我们通常所说的成员变量,事件可以让对象将某些特定行为发生的时间告知调用的程序。
1.2 函数成员
函数成员提供操作类中数据的功能,包括方法、属性、构造函数和终结器、运算符以及索引器。
1)方法。就是与类相关的函数,有静态方法和非静态方法之分。
方法的声明格式:
public bool IsSquare(Rectangle rect)
{
return (rect.Height == rect.width);
}
方法的调用:object.IsSquare(rectangle); object是类的实例,rectangle是类Rectangle的实例{
return (rect.Height == rect.width);
}
方法传递参数:在C#中所有的参数都是通过值来传递的,除非特别声明。(使用ref或者out关键字,
可迫使值参数通过引用来传递参数),例如:
static void SomeFunction(int[] ints, ref int i)
{
ints[0] = 100;
i = 100;//The change to i will persist after SomeFunction() exits
}
//调用该方法时,还需要添加ref关键字
SomeFunction(ints, ref i);
out和ref的使用形式大致相同,唯一的区别就是使用ref时,传递给方法的参数必须先初始化,而使用{
ints[0] = 100;
i = 100;//The change to i will persist after SomeFunction() exits
}
//调用该方法时,还需要添加ref关键字
SomeFunction(ints, ref i);
out关键字的时候,传递给方法的参数可以不初始化,但是C#规定必须在方法内部给参数赋值,如果
没有赋值,编译就会出错。
方法的重载:C#在重载方法的参数方面有一些小区别即可:
a)两个方法不能仅在返回类型上有区别
b)两个方法不能仅根据参数是声明为ref还是out来区分
2)属性
属性定义语法:
public string SomeProperty
{
get
{
return "This is the property value"
}
set
{
//do whatever needs to be done to set the property
}
}
{
get
{
return "This is the property value"
}
set
{
//do whatever needs to be done to set the property
}
}
get不带任何参数,且必须返回为属性声明的类型。set也不带参数,但编译器假定它带一个参数,其
类型也与属性相同,并表示为value。
如果省略set,属性就是只读属性。如果没有get,属性就是只写属性。
3)构造函数
C#中声明基本构造函数的语法与Java和C++中相同。构造函数的重载与其它方法的重载规则相同。
再没有显示定义任何构造函数的时候,编译器会自动提供默认的构造函数,如果提供了构造函数,
编译器就不提供默认构造函数。
a)静态构造函数
C#的一个新特征是可以给类编写无参数的静态构造函数。这种函数只执行一次。
编写静态构造函数的一个原因是,类有些静态字段或属性,需要在第一次使用类之前,从外部源
中初始化这些静态字段和属性。
class MyClass
{
static MyClass()
{
}
}
.NET运行库没有确保静态构造函数什么时候执行,所以不要把代码放在某个特定的时刻执行的静态构造函数中。也不能预计不同类的静态构造函数按照什么顺序执行。但是能确保静态构造函数最多执行一次,即在代码引用类之前执行。在c#中,静态构造函数通常在第一次调用类的成员之前执行。{
static MyClass()
{
}
}
静态构造函数只能访问静态成员,且没有访问修饰符,没有参数,且一个类也只能有一个静态构造函数。无参数的实例构造函数可以在类中与静态构造函数安全共存。
b)从其它构造函数中调用构造函数
一个类可能包含多个构造函数,它们之间可以相互调用
class Car
{
private string description;
private int nWheels;
public Car(string description, int nWheels)
{
this.description = description;
this.nWheels = nWheels;
}
public Car(string description):this(description,4)
{
}
}
{
private string description;
private int nWheels;
public Car(string description, int nWheels)
{
this.description = description;
this.nWheels = nWheels;
}
public Car(string description):this(description,4)
{
}
}
还可以对直接基类的构造函数进行调用,把this改成base。注意,初始化符中不能有多于一个的调用。且C#初始化符中只能调用另一个构造函数。
3)只读字段(readonly字段)
readonly关键字比const灵活得多,允许把字段设置为常量,但可以执行一些运算,以确定它的初始值。其规则是可以在构造函数中给readonly字段赋值,但不能在其它地方赋值。如果在构造函数中没有赋值,那么它的值就是数据类型的默认值,或者在声明的时候初始化。readonly字段还可以是实例字段,而不是静态字段。
二、结构
结构的定义与类完全相同。
三、类和结构的区别
区别在以下几个方面:
1.数据类型不同。类是引用类型,存储在托管堆中;结构是值类型,存储在堆栈中。
2.访问方式不同。
3.结构不支持继承。
4.结构的构造函数的工作方式与类有些不同。尤其是编译器总是给类提供一个无参数的默认构造函数,这是不允许替换的。
5.使用结构,可以指定字段如何在内存中布局