类
好久没有更新的博客!现在好多人在学习c#语法时都对类和结构体内容傻傻的分不清楚;个人觉得人要是对类和结构体分不清的话,说明你的c#还没有入门呢!对面向对象思想同样了解欠缺。这次打算分成三篇文章来写,先单独述说类,结构体,然后在讲讲它们之间的异同。不足之处请大家多多指导。
c#类
列表内容
类的定义:
什么是类呢?简单的来说,类是一种活动的数据结构。标准的定义是说:类是创建对象的模板,每个对象都包含这数据,并且提供了处理和访问数据的方法。类中定义了类的每个对象的可以包含什么数据和什么功能。当然了还可以简单的说:类是具有相同属性和相同方法的行为对象(模板).- 类的内容:类中无非只有两大块内容。数据成员和函数成员。
2.1数据成员:包含类的数据;一般来说包括:字段,常量,以及事件。
数据成员可以是静态数据,类的成员总是实例成员,除非用static进行显示声明。
字段:与类相关的变量;
常量:使用const关键字声明,常量即声明以后不能改变的量,与变量相对应。
事件:事件是一种特殊的委托的实例,或者说是受限制的委托,是委托一种特殊应用。
实例:
//这是字段的声明;
private int i = 6;
//这是对字段进行封装;
//VS中对字段快速封装快捷键为:ctrl+R+E
public int I { get => i; set => i = value; }
//这是常量的定义;
public const string name = "菜鸟";
//先定义委托类型
delegate void MyDelegate(object sender, EventArgs args);
//再定义事件实例
event MyDelegate Event;
2.2函数成员:函数成员提供了操作类中数据的某些功能。(方法,属性,构造方法和终结器(析构方法),运算符,和索引器)
方法:是与类类相关的函数,与数据成员一样,默认为实例成员。
属性:是可以从客户端访问的函数组,访问方式与访问类的字段类似。
构造函数:在实例化对象时自动调用的特殊函数,它们必须与类名相同,且不能有返回类型。一般用于初始化字段的值。
终结器(析构函数):类似与构造函数,但是在CLR检测到不再需要某个对象时调用它,它们的名称与类相同,但是前面有一个“~”符号,不可能预测到什么时候会调用终结器。
运算符:最简单的运算符就是+,-*,/运算了。
索引器:允许对象以数组或集合的方式进行索引。一般索引从0号开始的。
方法的声明:
访问修饰符 返回值类型 方法名称(参数)
{
//方法体
}
//这是一个简单的无返回值类型的方法声明
public void MyMethod(int i)
{
}
//这是一个返回类型学为int类型的方法声明
public int MyMethodTwo()
{
return 0;
}
方法既然可以声明,那么肯定可以去调用了,否则声明的方法毫无意义了!对吧!下面我们通过实例计算一个矩形的面积来看看方法是怎样调用的。
class Rectangle
{
//矩形的长
int length;
public int Length { get => length; set => length = value; }
//矩形的宽
int wide;
public int Wide { get => wide; set => wide = value; }
//计算面积的方法;
public void Area(int l,int w)
{
int area = l * w;
Console.WriteLine("矩形面积是:{0}",area );
}
static void Main(string[] args)
{
//实例化出一个对象r;
Rectangle r = new Rectangle();
//通过r去访问类中的成员;
r.length = 3;
r.wide = 4;
//通过对象r去调用类中的计算面积的方法;并且传入参数;
r.Area(r.length ,r.wide);
Console.ReadKey();
}
方法的参数传递:
按值传递参数
这是参数传递的默认方式。在这种方式下,当调用一个方法时,会为每个值参数创建一个新的存储位置。
实际参数的值会复制给形参,实参和形参使用的是两个不同内存中的值。所以,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。
比如:通过交换值来演示这个参数方法:
class MyClass
{
public void swap(int x, int y)
{
int temp;
temp = x; /* 保存 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 temp 赋值给 y */
}
static void Main(string[] args)
{
MyClass m = new MyClass();
/* 局部变量定义 */
int a = 100;
int b = 200;
Console.WriteLine("在交换之前,a 的值: {0}", a);
Console.WriteLine("在交换之前,b 的值: {0}", b);
/* 调用函数来交换值 */
m.swap(a, b);
Console.WriteLine("在交换之后,a 的值: {0}", a);
Console.WriteLine("在交换之后,b 的值: {0}", b);
Console.ReadLine();
}
}
结果:
在交换之前,a 的值:100
在交换之前,b 的值:200
在交换之后,a 的值:100
在交换之后,b 的值:200
按引用传递参数
引用参数是一个对变量的内存位置的引用。
当按引用传递参数时,与值参数不同的是,它不会为这些参数创建一个新的存储位置。引用参数表示与提供给方法的实际参数具有相同的内存位置。使用 ref 关键字声明引用参数:
class MyClass
{
public void swap(ref int x, ref int y)
{
int temp;
temp = x; /* 保存 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 temp 赋值给 y */
}
static void Main(string[] args)
{
MyClass m = new MyClass();
/* 局部变量定义 */
int a = 100;
int b = 200;
Console.WriteLine("在交换之前,a 的值: {0}", a);
Console.WriteLine("在交换之前,b 的值: {0}", b);
/* 调用函数来交换值 */
m.swap(ref a, ref b);
Console.WriteLine("在交换之后,a 的值: {0}", a);
Console.WriteLine("在交换之后,b 的值: {0}", b);
Console.ReadLine();
}
}
在交换之前,a 的值:100
在交换之前,b 的值:200
在交换之后,a 的值:200
在交换之后,b 的值:100
4.3按输出传递参数
return 语句可用于只从函数中返回一个值。
但是,可以使用 输出参数 来从函数中返回两个值。输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似。
class MyClass
{
public void getValue(out int x )
{
int temp = 5;
x = temp;
}
static void Main(string[] args)
{
MyClass m = new MyClass();
/* 局部变量定义 */
int a = 100;
Console.WriteLine("在方法调用之前,a 的值: {0}", a);
/* 调用函数来获取值 */
m.getValue(out a);
Console.WriteLine("在方法调用之后,a 的值: {0}", a);
Console.ReadLine();
}
}
在方法调用之前,a 的值: 100
在方法调用之后,a 的值: 5
写到这里,类中重要的东西基本上都讲完了,个人觉得类中的包含的数据成员和函数成员道理都是一样的,就拿方法来说吧!理解了如何声明和调用方法以后,类中其他的东西都是类似的。
最后讲讲实例化吧!我们都知道,写c#程序时不可能只使用一个类就完事了,不同的类可以去做不同的事情,类与类之间还可以互相继承等等;那么实例化就很重要了。即如何利用类创建对象:
使用我们自定义的类声明的变量也叫做对象,这个过程也叫做实例化。
比如:MyClass myClass = new MyClass ();
其中MyClass 是我们定义的类的名字,myClass是我们声明的变量(对象)的名字,后面的new是一个关键字,使用new 加上类型名()表示对该对象进行构造,如果不进行构造的话,这个对象是无法使用的。我们经常说c#面向对象思想,那么我们这个myClass 就是一个对象,这个对象可以帮助我们去访问类中的成员等等进行一些我们像要的操作。对于类中的继承,多态什么的这里现在不写,后期会和面向对象思想一起在博客中写的。。。