您的位置:首页 > 编程语言 > C#

C#学习笔记(四)类的进阶

2019-03-04 20:02 495 查看
版权声明:如有侵权,请及时删除,引用请标明出处,联系:2195971474@qq.com https://blog.csdn.net/khqxf/article/details/88119207

第六章 深入理解类

6.1 类的属性和函数

  1. 静态字段:它被类的所有实例所共享,所有实例访问同一内存位置,倘若该位置的值被某一实例修改,将对其他实例可见。我觉得在类中定义了静态字段和与之关联方法,在实例中通过调用这些方法来访问字段;类的实例伴随实例的创建而存在、消失而消亡,但即使没有类的实例成员也会存在类的静态成员。
//静态字段的使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Text;

namespace test5
{
class Program
{
public class D
{
int m1;          //类内的方法可以访问它们
static int m2;  //静态变
4000
量被类的某一个实列修改,对类的其他实列也是可见的。

public void SetValue(int val1,int val2)
{
m1 = val1;
m2 = val2;

}
public void ShowValue(string d)
{
Console.WriteLine("{0}:m1={1},2={2}",d,m1,m2);
}
}
static void Main(string[] args)
{
D d1 = new D();
D d2 = new D();
d1.SetValue(6,15);
d1.ShowValue("d1");     //显示d1的结果

d2.SetValue(5,16);
d2.ShowValue("d2");    //显示d2的结果

d1.ShowValue("d1"); //静态变量的值也随之被修改
}
}
}

执行结果:

  1. 静态函数成员:静态函数成员独立于类的实例,不能访问类的实例成员,但可以访问其他静态成员,不能通过 实例+点+成员名 访问静态方法,只能通过 类名+点+方法名访问静态方法。
public class Myclass
{
static int val = 16;//定义静态字段,并初始化
static void Mythod(int vall)    //定义静态方法,与静态字段相关联
{
val  = vall;
Console.WriteLine("{0}",val);
}
}

/*
Myclass mycl = new Myclass();
mycl.Mythod(18);     //错误,不能通过实例访问静态方法
*/
Myclass.Mythod(18);
  1. 成员常量:类似本地常量,只是它声明在类声明中而不是方法内,修饰词const,必须初始化,常量也是独立于类的实例存在,只是常量没有自己的存储位置,在编译时被编译器替换,静态量有存储空间。
  2. 属性:属于类的函数成员,有类型和名称,可读取或被赋值,不为数据存储分配内存,可以执行代码;属性有两个访问器,set访问器为属性赋值,get访问器获取属性的值。
  3. set访问器有一个隐形的值参value,与属性的类型相同,返回类型为void;get访问器没有参数,必有return返回语句,类型与属性的相同,访问器中的表达式可以是任何有效的计算表达式。
  4. 要写入属性,直接在等式左边用属性名为其赋值,要读取属性,把属性的名称用在表达式中,属性会根据是写入还是读取隐式调用相应的访问器,不能显示的调用访问器,故 属性名.set 或者 属性名.get 都是不正确的。
  5. 由于属性不为数据分配内存空间,常将属性与字段相关联,通过定义一个私有字段和公有属性,从类的外部访问字段。
public class Myclass
{
private int val ;  //定义私有字段
public int  Mythod   //定义一个公有属性,类型为整型,并与私有字段相关联
{
set{ val = value; }
get { return val; }
}
}

Myclass mycl = new Myclass();
mycl.Mythod = 16;
Console.WriteLine("{0}",mycl.Mythod);
  1. 当然访问器可以只有其一,只有set访问器的是只写属性,只有get访问器的是只读属性,都具有一定的安全性;自动实现属性要求同时有两个访问器,但访问器中无代码,后跟分号,允许对属性进行简单的读写操作。
public int  Mythod   //定义一个自动实现属性,类型为整型,可以在类实例化后对属性进行简单的读写操作
{
set;
get;
}
  1. 静态属性:有关键字static,不能访问来的实例成员——虽然类的实例成员可以访问它们;独立于类的实例存在;从类的外部访问时,不能通过实例名+点+属性名访问,只能通过类名访问静态属性。

  2. 实例构造函数:用于初始化类的实例的状态,在创建类的实例时,会被隐式调用;构造函数的名称与类名相同,没有返回值,当然构造函数也可以是含参的,从类的外部访问时,带访问修饰符public

public class Myclass
{
public Myclass()   //定于一个构造函数
{
Console.WriteLine("this is my class!");
}
}

Myclass mycl = new Myclass();   //创建类的实例时,会自动调用类的构造函数。
  1. 静态构造函数:在引用任何静态成员之前,在创建类的任何实例之前,常用于初始化类的静态字段;静态构造函数的名称与类名相同,没有返回值,有有关键字static,类中只能有一个静态构造函数,且是无参的静态构造函数没有访问修饰符
public class Myclass
{
static int val ; //定义静态字段
static  Myclass()  //定义一个静态构造函数,无参数古,无返回值,没有访问修饰符
{
val = 16;   //在静态构造函数中初始化静态字段
}
}
  1. readonly修饰符与const的比较:const字段只能在字段的声明语句中初始化,readonly字段可以在任意位置设置它的值,包括字段和构造函数;const字段必须在编译时确定其值,readonly字段的值可以在运行时确定;const的行为总是静态的,readonly字段可以是实例字段,也可以时静态字段,在内存中有存储位置。
  2. this关键字:在类中使用,是对类中当前实例的引用,只能用于实例构造函数和实例方法中以及属性和索引器的实例访问器。当你所定义的方法中,类中的字段与方法的参数名称相同时,可以用this 关键字加以区分,使用 this+点+字段 的形式。
public class Myclass
{
int val = 16;  //定义字段
public int Mythod(int val)  //定义一个方法 ,参数名与字段相同
{
return val>this.val?val:this.val;  //返回实参与字段中值较大者
}
}

6.2 索引器

  1. 索引器:不为数据分配内存,和属性一样,主要用来访问其他数据成员,与其他成员相关联同样具有set和get访问器,不同的是,属性表示单独的数据成员,索引器表示多个数据成员,索引器总是实例成员,不能声明为static,也可以自动实现属性,进行简单的读写操作。
  2. 索引器的声明:ReturnType this [Type params_list]{ get{…} set{…} },索引器没有名称,用this代替,参数列表至少有一个参数,且用方括号括起来。
  3. 索引器的set访问器:当索引器被赋值时,set访问器被隐式调用,并接受两项数据:隐式参数value,用于保存数据;至少一个索引参数,表示数据存储的位置。
    hell[0] = "hellow";
  4. 索引器的get访问器:当使用索引器获取值时,可以通过一个或者多个索引参数调用get访问器,索引参数指示要获取那个值。
    string str = khq[0];
  5. 示例如下:
//索引器的基本使用方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace test6
{
class Program
{
public class Myclass
{
static string Firstname;
static string Middlename;
static string Lastname;
public string this[int index]  //定义一个索引器
{
set
{
switch(index)    //switch语句的格式要牢记
{
case 0:Firstname = value;break;
case 1:Middlename = value;break;
case 2:Lastname = value;break;
default : throw new ArgumentOutOfRangeException("index is out of range!");

}
}
get
{
switch(index)
{
case 0:return Firstname;
case 1:return Middlename;
case 2:return Lastname;
default : throw new ArgumentOutOfRangeException("index is out of range!");
}
}
}
}
public class Myclass1
{
static int num1;
static int num2;
public int this[int index]   //在访问器中将索引作为条件判断。
{
set
{
if(index ==0){num1=value;}
else{num2 = value;}
}
get
{
return (index == 0)?num1:num2;
}
}
}
static void Main(string[] args)
{
Myclass m1 = new Myclass();
m1[0] = "自动化";
m1[1] = "1401班";
m1[2] = "加油!";
Console.WriteLine("m1[0]:{0},m1[1]:{1},m1[2]:{2}",m1[0],m1[1],m1[2]);

Myclass1 m2 = new Myclass1();
m2[0] = 16;
m2[1] = 18;
Console.WriteLine("m2[0]={0},m2[1]={1}",m2[0],m2[1]);
}
}
}

执行结果:

  1. 索引器的重载:索引器可以重载,由于索引器没有名称,this是必须的,重载时需要保证有不同的参数列表,即参数数目不同、参数类型不同。
  2. 访问器的访问修饰符:默认情况下,访问器的访问级别与属性或者索引器的访问级别一致,但也可以设置访问器的访问级别,注意:只有当属性或者索引器同时具有set和get两个访问器时才允许设置访问器的访问级别,且只能由一个具有访问修饰符;访问器的访问修饰符要比成员的访问级别更严格,public < protected internal < protected or internal < private,private的限制级别最高。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: