C#学习笔记之类(Class)

发布时间 2023-10-16 10:52:27作者: ycx-x

一、定义:以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