• .net学习之类与对象、new关键字、构造函数、常量和只读变量、枚举、结构、垃圾回收、静态成员、静态类等


    1.类与对象的关系
    类是对一类事务的统称,是抽象的,不能拿来直接使用,比如汽车,没有具体指哪一辆汽车
    对象是一个具体存在的,看的见,摸得着的,可以拿来直接使用,比如我家的那辆刚刚买的新汽车,就是具体的对象
    对象是根据类这个模板创建出来的,类里面有哪些特性或者功能对象里面也有,多不得,少不得

    2.new 一个对象做了哪些事情?
    Person person = new Person();new是一个运算符
    (1)在内存中开辟一块合适大小的空间
    (2)在这个空间里创建对象
    (3)调用这个对象的构造函数
    (4)返回这个空间的引用地址

    3.访问修饰符
    类的访问修饰符只有public和internal,内部类的访问修饰符可以为private

    4.属性
    属性的本质是一个get和一个set方法,而set方法中定义了一个参数名称为value,所以我们可以在set方法中访问value
    属性就是对字段的封装
    属性本身不存值,值是存在属性封装的对应的字段中
    只要类中的字段要被外界访问,就需要把这个字段封装为属性

    5.构造函数
    (1)构造函数访问修饰符一般情况下是public,没有返回值,方法的名称与类名相同
    (2)构造函数在创建这个对象的时候被自动调用,程序员无法手动调用
    (3)构造函数有什么用?如果我们希望在创建这个类的对象的同时需要执行一些代码,我们就可以将这些代码写到构造函数中
    (4)this关键字代表当前对象,当前运行在内存中的那一个对象,this关键字可以调用其他的构造函数
    (5)构造函数调用构造函数:
    public Dog(int age,string name):this(age)
    {

    }
    public Dog(int age)
    {

    }
    调用的时候:Dog dog = new Dog(2,"旺财");程序会先调用Dog(int age)构造函数,然后在调用Dog(int age,string name)构造函数
    (6)隐式构造函数:如果程序员没有为类手动添加构造函数,C#编译器在编译的时候会自动添加一个无参数的构造函数
    如果添加了构造函数,C#编译器在编译的时候则不会添加

    6.常量和只读变量
    (1)const修饰的数据叫做常量,
    常量一旦声明常量的值就不能改变,因为C#编译器在编译的时候声明常量的那句代码不见了,在使用常量的地方就用常量的值替换了
    比如
    const string name = "小明";
    Console.WriteLine(name);
    编译之后变为
    Console.WriteLine("小明");所以不能赋值

    readonly修饰的变量只读变量
    readonly string name = "小明";
    public Person()
    {

    }
    编译后
    readonly string name ;
    public Person()
    {
    this.name = "小明";
    }
    const和readonly的区别:
    const不能修改值,readonly只能在构造函数中修改值
    const在编译的时候就要确定值,readonly在运行时要确定值

    7.枚举
    枚举是一个值类型,每一个枚举成员都对应了一个整型的数值,这个数值默认是从0开始递增
    枚举和int类型转换:int a = (int)Direction.South; int i = 2; Direction d = (Direction)i;
    枚举和string类型转换:string str = "South"; Direction d = (Direction)Enum.Parse(typeof(Direction),str,true); //true表示忽略
    大小写
    枚举值所对应的数值默认是int类型的,可以在枚举的名字后面加一个冒号来指定这个数值的类型,只能是整型的(byte,short。。。)
    如:
    enum Direction:byte
    {

    }
    好处:限定变量的取值范围,在编码过程中不容易出错

    8.结构struct
    (1)结构中可以定义字段、属性、方法、构造函数,也可以通过new关键字来创建对象
    (2)无参数的构造函数无论如何C#编译器都会自动生成,所以我们不能显示的声明无参数的构造函数
    (3)在构造函数中必须要为结构体的所有的字段赋值
    (4)在构造函数中为属性赋值,不认为是对字段赋值,因为属性不一定是去操作字段
    (5)结构是一个值类型,在传递结构变量的时候,会将结构对象里面的每一个字段复制一份,然后拷贝到新的对象中
    (6)不能定义自动属性,因为自动属性会生成一个字段,而这个字段必须要求在构造函数中,而我们又不知道这个字段
    (7)声明结构体对象可以不new关键字,但是这个时候结构体对象的字段没有初始值,因为没有调用构造函数,而构造函数中必须为字段赋
    值,所以通过new关键字创建的结构体对象的字段就有默认值。
    (8)当我们要表示一个轻量级的对象的时候,就可以定位结构以提高速度。根据传值的影响来选择,希望传引用就定义为类,希望传拷贝就
    定义为结构

    9.垃圾回收
    托管代码:被CLR管理的代码
    非托管代码:不被CLR管理的代码
    应用程序域:当。net应用程序在CLR中运行的时候,CLR会创建一个单独的应用程序域,让。net应用程序在应用程序域中运行
    分配在栈空间的变量一旦执行完其所在的作用域(即"{ }"中),这个变量就会CLR立即回收
    分配在堆里面的对象没有任何对象引用的时候,这个对象就被标记为“垃圾对象”,等待垃圾回收期回收。
    GC会定时的清理堆空间中的垃圾对象,GC清理垃圾对象的频率程序员无法决定,由CLR自动控制
    当一个对象被标记为“垃圾对象”的时候,这个对象不一定立即被回收
    垃圾回收运行机制:
    垃圾回收会根据应用程序的运行情况来使用合适的算法,其中一种算法如下:
    CLR会预先开辟一块空间,当创建对象的时候会放在第0代的内存中,当第0代的空间满的时候,GC开始回收第0代,不被标记垃圾的对象会移
    动到第1代内存中,然后第0代空间变为空,当再次创建对象的时候会存储在第0代空间,一直这样重复,第1代空间不满的时候不会回收。当
    第1代空间满的时候,会垃圾回收第1代,然后把老的对象移动到第1代,新对象存储在第0代。第1代到第2代是和第0代到第1代一样,当三代
    都满的时候会报异常说内存溢出

    GC.GetGeneration(p)获取指定对象是属于第几代,总共有3代,从0开始,0,1,2
    GC.Collect();立即让垃圾回收器对所有的代进行垃圾回收
    GC.Collect(0);表示对第0代回收GC.Collect(1);表示对第0代和第1代回收

    Person p = new Person();
    GC.GetGeneration(p);值为0
    GC.Collect();
    GC.GetGeneration(p);值为1
    GC.Collect();
    GC.GetGeneration(p);值为2
    GC.Collect();
    GC.GetGeneration(p);值为2
    10.析构函数
    析构函数不能有访问修饰符,不能有参数,所有不能被继承或重载,在对象被垃圾回收器回收的时候,析构函数被GC自动调用,当没有垃圾
    对象的时候不会被调用,
    执行一些清理善后的操作
    ~Person()
    {

    }
    11.静态成员
    (1)在这个类第一次被加载的时候,这个类下面所有的静态成员会被加载,静态成员是属于类的,实例成员是属于对象的
    (2)静态成员只能被创建一次,所以静态成员只有一份,实例成员有多少个对象就创建多少次
    (3)静态成员被创建在静态存储区中,一旦创建直到程序退出才会被回收
    (4)什么时候定义为静态的?变量需要被共享的时候,方法需要被反复调用的时候
    (5)静态方法中不能直接调用实例成员,因为静态方法被调用的时候,对象有可能没有创建
    (6)this/base关键字在静态方法中不能使用,因为有可能对象不存在
    (7)在实例方法中可以调用静态成员,因为这个时候静态成员肯定存在
    静态成员和实例成员区别:
    (1)生命周期不同,静态成员在程序退出时才会被回收,实例成员则在该对象被垃圾回收器回收时才会被回收
    (2)存储的位置不同,静态成员存储在静态存储区中,实例成员存储在堆的对象里面

    12.静态类
    (1)静态类中只能声明静态成员
    (2)静态类中不能有实例构造函数
    (3)静态类中不能被实例化,因为没有实例成员,实例化无意义
    (4)静态类不能被继承,因为本质是一个抽象的密封类,所以不能被继承也不能被实例化
    (5)如果一个类下面的所有成员都需要被共享,那么就可以把这个类定义为静态类
    (6)不能声明一个静态类的变量,比如静态类Person p;
    静态构造函数:非静态类也可以有静态构造函数
    静态类的成员第一次被访问之前就会执行静态构造函数
    静态构造函数只被执行一次

  • 相关阅读:
    Mac保留Python2安装Python3(Anaconda3)
    Mybatis Plugin 以及Druid Filer 改写SQL
    Jackson替换fastjson
    Java单元测试 Http Server Mock框架选型
    应用中有多个Spring Property PlaceHolder导致@Value只能获取到默认值
    RabbitMQ Policy的使用
    Collectors.toMap不允许Null Value导致NPE
    php 删除标签
    php 替换标签
    jquery拼接html
  • 原文地址:https://www.cnblogs.com/yxlblogs/p/3386960.html
Copyright © 2020-2023  润新知