类与对象

基本定义 #

类: #

定义:相当于理型,比如人类

对象: #

相当于实例,比如哆啦a孟

属性(Properties): #

相当于特征类型,比如可写作Name,用于保护字段的值,对 字段的赋值取值进行限定,使用时用Ctrl+R+E可根据字段快速出现属性

字段(Field): #

相当于具体特征,比如可写作_name,用于承载具体的属性如姓名身高体重等,使用时可以不public,默认private,只通过属性来调用(在使用中必须是私有的)

方法(Method): #

相当于行为,比如人类能够实现的跑跑跳跳等行为

tips:类与结构的取别在于结构不具备封装、继承、多态等特征

举例:
人的类:

public class Person
{
    public string _name//字段
    public string Name//属性
    {
        get{return _name;}
        set{_name=value;}
    }
    public int _age
    {
        get{return _age;}
        set{
            if(value<0||value>0)
            {
                value=0;
            }
            _age=value;
            }
    }
    public void Skill()
    {
        Console.write("{0}dance",this.Name);
    }
}

在程序中使用人的类创建实例:

Class Program
{
    Person binbin=new Person();
    binbin.Name="哆啦a孟";
    binbin.Age=5;
}

关键字 #

this #

  1. 代表当前类的对象,用法:this.属性名/字段名
  2. 在类中显示调用本类的构造函数,用法:this()

new #

  1. 创建对象
  2. 隐藏从父类继承的成员(当父类和子类有成员同名时)隐藏后此类调用不到父类的成员,所以尽量不要写一样的名字

构造函数(构造器) #

形式:

public 类名(各种参数)
{
    各种参数的赋值
}
  • 构造函数用来创建对象,并且可以在构造函数中对对象进行初始化
  • 是构造函数时用来创建对象的特殊方法,方法名和类名一样,没有返回值,也不用写void
  • 构造函数可以有参数,new对象的时候传递函数参数即可
  • 如果自己不指定构造函数,则类会有一个默认的无参构造函数,在指定构造函数后会自动被替换。如果自己需要一个无参构造函数,需要自己写
  • 构造函数可以重载,也就是有多个参数不同的构造函数
  • 认识类图
  • 构造函数必须用public写在类里
  • 创建对象时会自动执行构造函数

析构函数 #

形式:

~类名()
{

}

作用方式:在程序结束的时候才执行
用处:帮助释放资源,如果需要马上释放资源,就使用析构函数

静态与非静态 #

  • 非静态类中可以有静态成员与非静态成员
  • 静态成员需要用类名去调用,如类名.成员名
  • 非静态成员要用实例化后的实例名去调用,如对象名.成员名,或this.成员名
  • 静态函数中只能访问静态成员,不能访问实例成员
  • 非静态函数中都可以使用
  • 静态类中只能使用静态成员
  • 静态类不能被实例化(不能创建对象)
    使用:
  • 如果要将类当作工具使用,可以考虑将其写成静态类,比如console.writeline
  • 静态类在整个项目中资源共享
  • 只有在程序全部结束之后,静态类才会释放资源
  • 非静态类不占内存(创建对象时占内存),静态类占内存(堆、栈、静态存储区域)
  • 注:释放资源时使用的是GC,Garbage Collection 垃圾回收器。

类和对象的使用 #

声明类需要class关键字
类的属性和方法写在大括号{}中
实例化:类名 实例化名= new 类名();
类不占内存,对象占内存
类使用关键字new来实例化对象
一个类可以实例化多个对象
对象可以使用类定义的属性和方法

声明属性 #

属性在c#中比较独特,既不同于方法也不同于字段

属性遵循[[Csharp_变量#变量的命名|大驼峰命名法]]

属性最常用的书写方法:

publcintage{get;set;}
访问修饰符属性类型属性名关键字关键字
如果属性中具有get关键字,说明可以获取该属性的值
如果属性中具有set关键字,说明可以向该属性设置值

如果需要给不认识的类的属性赋值,可以

  • 光标浮在属性上看需要什么字段
  • 等号后空格自动出现

访问修饰符 #

访问修饰符功能
public公有的,所有的类都可以访问
private私有的,当前类内部可以访问
protected受保护的,当前类以及继承它的子类可以访问
internal内部的,只限于本项目内可以访问,其他不能访问
protected internal内部保护访问,只限于本项目内部或子类访问,其他类不能访问

只有public和internal才能修饰类

类默认是internal

在同一个项目中,internal和public是一样的

可访问性不一致:

子类的访问权限不能高过父类的访问权限

访问级别约束:

父类子类访问修饰符要保持一致

方法的访问修饰符要和方法参数的访问修饰符保持一致

静态方法、属性

静态属性和方法通过static关键字修饰

静态属性可以通过类型直接获取,非静态则必须通过实例化的对象后去

静态类

静态类通过static关键字修饰

一般情况下类型不需要使用静态修饰,只有当类型中存在扩展方法时需要使用静态类

This 表示当前类的对象,可在类的定义中使用

索引器 #

索引器为访问类或者结构体中封装的列表或字典型数据元素提供了自然的访问接口。索引器和属性很相似,但索引器通过索引值而非属性名称访问数据元素。例如string类具有索引器,可以通过int索引访问其中每一个char的值。

string s="hello";
console.Writeline(s[0]);//'h'
console.Writeline(s[3]);//'l'

使用索引器的语法就像使用数组一样,不同之处在于索引参数可以是任意类型。

索引器和属性具有相同的修饰符,并且可以在方括号前插入?以支持使用null条件运算:

string s=null;
console.writeline(s?[0]);//啥也不写出来,也不报错

索引器的实现 #

编写所引起首先要定义一个名为this的属性,并将参数定义放在一对方括号中,例如:

class Sentence
{
    string[] words="The quick brown fox".Spilt();
    public string this[int wordNum]//索引器
    {
        get{return words[wordNum];}
        set{words[wordNum]=value;}
    }
}

以下是该索引器的使用方式:

Sentence s = new Sentence();
console.Writeline(s[3]);//fox
s[3]="kangaroo";
console.Writeline(s[3]);//kangaroo

一个类可以定义多个参数类型不同的索引器,一个索引器也可以包含多个参数:

public string this[int arg1,string arg2]
{
    get{...}set{...}
}

如果忽略set访问器,则索引器就是只读的,并且可以使用c#6中的表达式语法来简化定义:

public string this[int wordNum]=>words[wordNum];

CLR索引器的实现
索引器在内部会编译名为get_item和set_item的方法,如下所示:

public string get item(int wordNum){...}
public void set_item(int wordNum, string value){...}
更新 2023年 2月 8日