C#学习笔记之类(Class)
一、定义:以class关键字开始,后跟类的名称。类的主体(成员)包含在一对花括号内。
一般形式:
<access specifier> class class_name { //变量 <access specifier> <data type> variable1; <access specifier> <data type> variable2; ... <access specifier> <data type> variablen; //方法 <access specifier> <return type> Method1(parameter_list) { //方法主体(块) } <access specifier> <return type> Method2(parameter_list) { //方法主体(块) } ... <access specifier> <return type> Methodn(parameter_list) { //方法主体(块) } }
需要注意:
1、 <access specifier>为访问标识符,指定了类对其成员的访问规则,类的默认访问标识符为:internal,成员的默认访问标识符为:private
public:公有访问,不受任何限制 |
private:私有访问,只限于本类成员访问,子类、实例都不能访问 |
protected:保护访问,只限于本类和子类访问,实例不能访问 |
internal:内部访问,只限于本项目内访问,其他项目不能访问 |
protected internal:内部保护访问,仅限于本项目或子类项目访问,其他项目不能访问 |
2、<data type>指定了变量的类型;
3、<return type>指定了数据的返回类型;
4、访问类的成员需要使用点(.)运算符,点运算符链接了对象的名称和成员的名称;
5、对象是类的实例,构成类的方法和变量称为类的成员
二、类的实例化
1、定义:类的实例就是类的对象,定义类后进行实例化即可访问类中的成员。
2、类的实例化:使用关键字 new
语法:类 实例名 = new 类(); 实例:Test testItem = new Test();
3、类的成员的访问
①静态成员:属于类所有,用static标识,类所有实例共享,无论有多少实例或副本,只占用其中一块区域,直接使用【类名.方法名】调用。例如:Test.Calculate();
②非静态成员:属于实例(对象)所有,没有标识,类的每个实例都创建一个内存域,调用目标类的方法或者属性时必须先实例化目标类。例如:实例名.属性、实例名.方法();
③类的成员包括:字段、属性、方法(函数)、事件等
a) 字段:通常使用static/readonly,一般形式为:<Type> <变量名称>
- 字段是类的一个私有变量,通常为私有的,访问标识符默认为 private;
- 字段定义通常以小写字母开头
实例
static int count = 2;//静态字段 readonly int count = 3;//只读字段
b) 属性
- 属性是类的一个公有变量,通常为公有的,访问标识符默认为:public
- 属性有get和set两个方法(访问器)
- get访问器返回与属性声明类型相同的数据,表示的是调用时可得到内部的字段的值或者引用;set访问器没有显示可设置的参数,但set访问器有一个隐形参数value,它的作用是调用时可以给属性内部的字段或者引用赋值
- 因为类的字段默认为私有(private),属性默认为公有(public),所以在面向对象的开发过程中,通常使用修饰符public来声明公有属性
- 属性可以忽略get访问器或set访问器,但是不能同时忽略两个访问器
实例
namespace Test { internal class Program { //字段 private static int count = 5; private readonly int index = 9; private string name; //属性 public string Name => name;//等效于public string Name {set; get;}此模式下的set可忽略,get访问器不可忽略 //public string Name {set => name = value;}此模式下可忽略set访问器或者get访问器,但不能同时忽略
}
}
c) 方法(函数)
声明:
<Access Specifier> <Return Type/void> <Method Name>(Parameter List) { Method Body }
- <Access Specifier>:访问修饰符,这个决定了该类的变量或方法对于另一个类的可见性
- <Return Type/void>:返回类型,一个方法可以返回一个值,返回类型是方法返回的值的数据类型。如果方法不返回任何值,则返回类型为void
- <Method Name>:方法名称,是一个唯一的标识符,且是大小写敏感的。不能与类中其他标识符(方法名称)相同
- <Parameter List>:参数列表,使用圆括号括起来,该参数是用来传递和接收方法的数据。参数列表是指方法的参数类型、顺序和数量,参数是可选的,一个方法中可以不包含参数
- <Method Body>:方法主体,包含了完成任务所需的指令集调用 : <类名>.<实例对象名>.<方法名>(<实例参数>)
静态方法只能调用静态字段/属性/方法,不允许调用非静态字段/属性/方法
实例
internal class Program { private string name = "Lisa"; public string Name => name; static void Main(string[] args) { bool re = ReturnMethod($"Name:{Name}"); Console.WriteLine(re) } public bool ReturnMethod(string message) { Console.WriteLine(message); return true; } } 编译上述代码会报错,对象引用对于非静态的字段、方法或属性“Program.Name”是必需的,因为Main方法为静态方法,而ReturnMethod方法和字段name、属性Name都是非静态的,可修改为以下方式 internal class Program { private static string name = "Lisa"; public static string Name => name; static void Main(string[] args) { bool re = ReturnMethod($"Name:{Name}"); Console.WriteLine(re) } public static bool ReturnMethod(string message) { Console.WriteLine(message); return true; } } 或者
internal class Program { private string name = "Lisa"; public string Name => name; static void Main(string[] args) { Program program = new Program(); bool re = program.ReturnMethod($"Name:{program.Name}"); Console.WriteLine(re) } public bool ReturnMethod(string message) { Console.WriteLine(message); return true; } } 运行后结果为:
Name:Lisa
True
三、参数传递(方法参数)
1、值参数:不含任何修饰符,复制参数的实际值给方法的形式参数,形参的改变不会改变或影响实参的值。
实例
namespace Test { class Program { public void WriteLineMessage(string message) { message = "Method Name"; } static void Main(string[] args) { Program program = new Program();
string message = "Main Name";
Console.WriteLine("Message1:{0}",message);
program.WriteLineMessage();
Console.WriteLine("Message2:{0}",message);
Console.ReadKey();
}
}
}
输出结果为:
Message1:Main Name
Message2:Main Name
2、引用参数:以 ref 修饰符声明。当形参的值发生变化时,实参的值也随之改变。
需注意:若要使用因引用参数 ref ,则方法定义和调用都必须显示使用 ref 关键字(即定义和调用都需有 ref 关键字),并且传递 ref 参数前必须初始化。有进有出。
实例
namespace Test { class Program { public void WriteLineMessage(ref string message) { message = "Method Name"; } static void Main(string[] args) { Program program = new Program(); string message = "Main Name"; Console.WriteLine("Message1:{0}",message); program.WriteLineMessage(ref message); Console.WriteLine("Message2:{0}", message); Console.ReadKey(); } } } 输出结果为: Message1:Main Name Message2:Method Name
3、输出参数:以 out 修饰符声明。
需注意:在方法声明和方法调用时都必须明确的指定 out 关键字,可以返回多个值,并且在方法返回前,必须对 out 参数赋值。只出不进。
实例
namespace Test { class Program { public void WriteLineMessage(out string message) { message = "Method Name"; } static void Main(string[] args) { Program program = new Program(); //string message = "Main Name"; //Console.WriteLine("Message1:{0}", message); program.WriteLineMessage(out string message); Console.WriteLine("Message2:{0}", message); Console.ReadKey(); } } } 输出结果: Message2:Method Name
4、数组型参数:以 params 修饰符声明(可变长度的参数列表)。只能包含一个 params 参数,且带 params 关键字的参数类型必须是一维数组
需注意:
①数组与参数数组的区别:
- 数组作为参数传递时,当调用函数时需要使用 new 关键字进行初始化;
- 参数数组传递时,不需要 new 关键字初始化,且可指定类型的参数数组或不发送参数
②使用params时注意事项
- 若形参表中含有一个参数数组(params形参数组),则该参数数组必须位于形参参数列表的最后,且只能声明一次。即在方法声明中的 params 关键字后不允许有其他任何参数,并且在方法中 params 只能声明一次
- 参数数组必须是一维数组
- 不允许将 params 修饰符与 ref 和 out 修饰符组合起来使用
- params 修饰的参数数组,可以为任意类型,只需在设置数组类型时为 object 即可
- 若实参是数组则按引用传递,若实参是变量或者表达式则按值传递
- params后必跟数组。作用是把不定量的、同类型的参数装入这个数组中
实例
namespace Test { class Program { public void WriteLineMessage(params object[] list) { foreach (var item in list) { Console.WriteLine("ParamsList:{0}", item); } } public void WriteLineMessage2(object[] list) { for (int i = 0; i < list.Length; i++) { Console.WriteLine("List:{0}",list[i]); } } static void Main(string[] args) { Program program = new Program(); program.WriteLineMessage(); program.WriteLineMessage(1,2,3,4); program.WriteLineMessage(1,'a',"params list"); program.WriteLineMessage2(new object[] { 1, 2, 5, 6 }); program.WriteLineMessage2(new object[] { 1, 'a', "list" }); Console.ReadKey(); } } } 输出结果: ParamsList:1 ParamsList:2 ParamsList:3 ParamsList:4 ParamsList:1 ParamsList:a ParamsList:params list List:1 List:2 List:5 List:6 List:1 List:a List:list