C#基础知识--Day07

Day 07

枚举

简单枚举

  1. 列举某种数据的所有取值。
  2. 作用:增强代码的可读性,限定取值。
  3. 语 法 : enum 名字{值1,值2,值3,值4}。
  4. 枚举元素默认为int, 准许使用的枚举类型有byte、sbyte、 short、ushort、int、uint、long或ulong。
  5. 每个枚举元素都是有枚举值。默认情况下,第一个枚举的 值为0,后面每个枚举的值一次递增1,可以修改值,后面枚举数的值依次递增。

标志枚举

  1. 可以同时赋多个枚举值。
  2. 条件:
    –任意两个枚举值做按位或运算的结果不能与其他枚举值 相同。
    –使用[Flags]特性标记枚举类型。
[Flags]//标志枚举
enum PersonStyle
{
    
    
    tall = 1,       //00000001
    rich = 2,       //00000010
    handsome = 4,   //00000100
    white = 8,      //00001000
    beauty = 16     //00010000
}

按位运算符

1. 按位或运算:

  1. 对应的两个二进制位有一个为1时,结果位为1。
  2. 用于同时选择多个枚举值。
  3. 例 如 : 2 与 3 做按位或运算,结果仍然为3
    0010 | 0011 --> 0011

2. 按位与运算:

  1. 对应的两个二进制位都为1时,结果位为1。
  2. 用于判断标志枚举是否包含某个枚举值。
  3. 例如:2 与3做按位或运算,结果仍然为3
    0010 & 0011 --> 0010

注意

  1. 选择多个枚举值
    运算符|(按位或): 两个对应的二进制位中有一个为1,结果位为1
    tall | rich ==> 0000000000 | 0000000001 ==> 0000000001

  2. 条件:(枚举多选的时候两者要都写
    1 . 任意多个枚举值做 | 运算 的 结果,不能与其他枚举值相同 (值以2的n次方递增)
    2 . 定义枚举时,使用 [Flagsh] 特性修饰

  3. 判断标志枚举 是否包含指定枚举值
    运算符&(按位与):两个对应的二进制位中都为1,结果位为1
    0000000011 & 0000000001 ==> 0000000001

static void Main1(string[] args)
{
    
    
    // 数据类型
    //(1)值类型:直接存储数据
    //(2)引用类型: 存储数据的引用(内存地址)
    //(3)方法执行在栈中,执行完毕清除栈帧。
    //(4)局部变量的值类型:声明在栈中,数据在栈中
    //(5)局部变量的引用类型:声明在栈中,数据在堆中,栈中存储数据的引用。
    //(6)区分修改的是栈中存储的引用,还是堆中数据

    PrintPersonStyle(PersonStyle.tall | PersonStyle.rich);

    //数据类型转换
    // int ==> Enum
    PersonStyle style01 = (PersonStyle)2;
    PrintPersonStyle((PersonStyle)2);

    // Enum ==> int
    int enumNumber = (int)(PersonStyle.beauty | PersonStyle.white);

    //string ==> Enum
    //"beauty"
    PersonStyle style02 = (PersonStyle)Enum.Parse(typeof(PersonStyle), "beauty");
    // Enum ==> string
    string strEnum = PersonStyle.handsome.ToString();
}

//多选和包含
private static void PrintPersonStyle(PersonStyle style)
{
    
    
//多选
    if (style == PersonStyle.tall)
        Console.WriteLine("大个子");
    if (style == PersonStyle.rich)
        Console.WriteLine("土豪");
    if (style == PersonStyle.handsome)
        Console.WriteLine("英俊");
    if (style == PersonStyle.white)
        Console.WriteLine("洁白");
    if (style == PersonStyle.beauty)
        Console.WriteLine("漂亮");
//包含
    if ((style & PersonStyle.tall) == (PersonStyle.tall))
        Console.WriteLine("大个子");

}

类和对象

  1. 面向对象: 一种软件开发的思想,指导程序员如何分析、
    解决问题。
  2. 是一个抽象的概念,即为生活中的”类别”。
  3. 对象是类的具体实例,即归属于某个类别的”个体”。
  4. 例如:学生是一个类,表示一种类型,”xx同学”则是一个对象。
  5. 名词类型的共性,作为数据成员。
  6. 动词类型的共性,作为方法成员。

创建类

  1. 语法:
访问级别 class 类名
{
    
    
    类成员...
}
  1. 通常每个类都在一个独立的 c# 源文件中。
  2. 创建新的类意味着在当前项目中产生了一种新的数据类型

创建对象

  1. 语法:
    类名引用名;
    引用名= new 构造函数(参数列表);
  2. 创建对象的过程也称为”实例化”

访问修饰符

  1. 用于修饰类及类成员的访问可见范围。
    public:所属类的成员以及非所属类的成员都可以访问。
    private:只有所属类的成员才能访问。[类成员的默认级别]

属性

属性

  1. 对字段起保护作用,可实现只读、只写功能。
  2. 本质就是对字段的读取与写入方法。
  3. 语法:
[访问修饰符]数据类型属性名
{
    
    
     get {
    
     return 字段;}
     set {
    
     字段= value;}
}
  1. 通常一个公有属性和一个私有字段对应。
  2. 属性只是外壳,实际上操作的私有字段。

自动属性

  1. 当属性访问器中不需要任何其他逻辑时,使用自动属性可以更加简洁。
  2. 本质就是一个字段两个方法。
  3. 语法:
[访问修饰符]数据类型属性名{
    
     get;  set;}
例如:
public int Id {
    
    get; set;}

在这里插入图片描述

构造函数

定义

  1. 提供了创建对象的方式,初始化类数据成员的特殊方法。
  2. 语 法 :
[访问修饰符]类名([参数列表])
{
    
    
     初始化 ...
}

特点

  1. 与类同名。
    没有返回值,也不能写void。
  2. 不能被直接调用,必须通过new 运算符在创建对象时才会自动调用。
  3. 每个类都必须至少有一个构造函数,若不提供,编译器自动生成一个无参构造函数。
  4. 如果程序员定义了构造函数,则编译器不会再提供。

this关键字

  1. 表示当前对象的引用。
  2. 访问当前类成员时,使用this关键字,可以提高代码的可读性;在没有歧义的情况下,也可以省略。

类结构

访问级别 class类名
{
    
    
    字段:存储数据
    属性:保护字段
    构造函数:提供创建对象的方式,初始化类的数据成员
    方法:向类的外部提供某种功能
}

Static

静态成员变量

  1. 使用static关键字修饰的成员变量。
  2. 静态成员变量属于类,类被加载时初始化,且只有一份。
  3. 实例成员变量属于对象,在每个对象被创建时初始化,每个对象一份。
  4. 特点:存在优先于对象,被所有对象所共享,常驻内存。

静态构造函数

  1. 初始化类的静态数据成员。
  2. 仅在类被加载时执行一次。
  3. 不允许使用访问修饰符。

静态构造函数

  1. 初始化类的静态数据成员。
  2. 仅在类被加载时执行一次。
  3. 不允许使用访问修饰符。

静态方法

  1. 通过引用调用实例方法时,会隐式的传递对象引用,以便在方法内部可以正确访问该对象成员变量。
  2. 通过类名调用静态方法时,因为没有具体对象,所以在static方法中不能访问实例成员。

静态类

  1. 使 用static关键字修饰的类。
  2. 不能实例化,只能包含静态成员。
  3. 静态类不能被继承,但是静态方法、属性都可以被继承。

适用性

  1. 利:单独空间存储,所有对象共享,可直接被类名调用。 弊:静态方法中只能访问静态成员,共享数据被多个对象访问会出现并发。
  2. 适用场合:
    1.所有对象需要共享的数据。
    2.在没有对象前就要访问成员。
    3.工具类适合做静态类(常用,不需要过多数据)。
例子——主函数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Day07
{
    
    
    internal class Program
    {
    
    
        static void Main2()//具体的老婆
        {
    
    
            //声明Wife类型的 引用
            Wife wife01;//声明(栈上)存的是空

            //指向Wife类型的对象(实例化Wife类型对象)
            wife01 = new Wife();//就是创建了一个wife类型的对象(都是默认值)
            wife01.SetName("名字");
            wife01.SetAge(18);
            Console.WriteLine(wife01.GetName());
            Console.WriteLine(wife01.GetAge());

            Wife wife02 = wife01;
            //wife02 = new Wife();//加上这句话对原来没影响
            wife02.SetName("木南");
            Console.WriteLine(wife01.GetName());//?

            //调用不想写私有属性,公开方法时这样写
            Wife wife03 = new Wife();
            wife03.Name = "名字2";//执行 Name 的Set代码块

            //想同时创建对象 并 赋值
            Wife wife04 = new Wife("名字3",19);

            //构造函数调用其他的构造函数
            Wife wife05 = new Wife("名字3");

        }


        static void Main3()
        {
    
    
            Wife w01 = new Wife();
            w01.Name = "01";
            w01.Age = 35;
            Wife w02 = new Wife("02", 30);//构造函数:直接可以赋值

            Wife[] wifeArray = new Wife[10];
            wifeArray[0] = w01;
            wifeArray[1] = w02;
            wifeArray[2] = new Wife("03", 40); 
            wifeArray[3] = new Wife("04", 20); 
            wifeArray[4] = new Wife("05", 25);

            //练习1 : 查找年龄最小的老婆
            GetWifeByMinimumAge(wifeArray);
        }


        private static Wife GetWifeByMinimumAge(Wife[] wifes)
        {
    
    
            Wife minWife = wifes[0];
            for (int i = 1; i < wifes.Length; i++)
            {
    
    
                if (minWife.Age > wifes[i].Age)//比较的是具体的年纪
                    minWife = wifes[i];//改变的是栈上面的引用
                //minWife.Age = wifes[i].Age;//这样子不行,因为两个人家已经确定的数据不能改变
            }
            return minWife;
        }

    }
}
例子——Wife类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Day07
{
    
    
    /// <summary>
    /// 定义老婆类
    /// </summary>
    class Wife//这里面都是抽象的老婆
    {
    
    //-数据成员(公用的地方,放置类)

        //--私有的 private,只能大括号里面用

        //---字段:存储数据(首字母小写)
        private string name;

        //不想写私有属性,公开方法的可以下面这样写
        //属性:保护字段  本质就是两个方法
        public string Name //属性首字母大写
        {
    
    
            //读取时保护
            get       //本质是下面GetName方法
            {
    
     return name; }//如果写成Name(属性内部返回属性,会导致栈溢出)

            //写入时保护  value 要设置的数据(希望传入的数据)
            set       //本质就是下面SetName方法
            {
    
     this.name = value; }
        }
        private string sex;
        private int age;

        public int Age
        {
    
    
            get
            {
    
    
                return this.age;
            }
            set        //在方法中修改数据
            {
    
    
                if (value <= 19 && value >= 18)

                    this.age = value;
                else

                    throw new Exception("我不要");
            }
        }


        //构造函数
        //构造函数:提供了创建对象的方式,常常用于初始化类的数据成员
        //一个类若没有构造函数,那么编译器会自动提供一个无参数构造函数
        //一个类若具有构造函数,那么编译器不会提供无参数构造函数
        //本质:方法
        //特点 : 没有返回值
        public Wife() //若不想让这个类创造对象,就让构造函数(类)私有化(private)
        {
    
    

        }

        public Wife(string name) : this()
        {
    
     //Wife(); 若要调用上面的无参数构造函数
          //在构造函数后面写 : this()
            this.Name = name;
        }


        public Wife(string name, int age)//写形参,想同时创建对象 并 赋值
        {
    
    
            this.name = name;//构造函数如果为字字段赋值,属性中的代码块不会执行
            //下面的不会执行(构造函数里面给字段还是给属性赋值没有要求,但如果有逻辑判断就要给属性赋值)
            //this.Age = age;
            this.Age = age;
        }




//构造函数:提供了创建对象的方式,常常用于初始化类的数据成员//一个类若没有构造函数,那么编译器会自动提供一个无参数构造函数
//特点 : 没有返回值

        int a;

        //方法成员
        //有“筛选条件”的需求要搭配:私有的类,配公开的方法(写成私有的,就是为了读写,做数据上的验证)
        public void SetName(string name)//name是局部变量
        {
    
    
            int a = 1;
            Console.WriteLine(this.a);//找的是方法外的那个a
            //this 这个对象(引用)
            this.name = name; //成员变量//这个参数给数据成员
        }
        public string GetName()
        {
    
     //两者都行有没有this
            //return this.name;
            return name;
        }
        public void SetAge(int age)
        {
    
    
            //如果类定义者再有逻辑需求,就可以在方法内部去干
            if (age <= 19 && age >= 18)
            {
    
     this.age = age; }
            else
                throw new Exception("不要");
        }
        public int GetAge()
        {
    
    
            return this.age;
        }

    }
}

结构 struct

  1. 定义:用于封装小型相关变量的值类型。与类语法相似, 都可以包含数据成员和方法成员。但结构属于值类型,类
    属于引用类型。
  2. 适用性:
    表示点、颜色等轻量级对象。如创建存储1000个点的数组, 如果使用类,将为每个对象分配更多内存,使用结构可以节约资源。

定义结构体

  1. 使用 struct 关键字定义。
  2. 除非字段被声明为 const 或 static,否则无法初始化。
  3. 结构不能继承,但可以实现接口。
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/b634fc1de6bc43138fbde10b63b6d3ab.png

构造函数

  1. 结构总会包含无参数构造函数。
  2. 构造函数中必须初始化所有字段。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_61561568/article/details/137121467