引用刘铁猛老师(大神)内容:https://www.bilibili.com/video/BV13b411b7Ht?p=23
1.面向对象主要是指封装,继承,多态。
2.类
类是一种数据结构,他可以包含数据成员(常量和字段),函数成员(方法,属性,事件,索引器,运算符,实例构造函数,静态构造函数和析构函数)以及嵌套类型。
(1)类是一种抽象数据结构,是一种抽象的结果。比如一个学生,我们可以抽取这个学生的姓名学号,电话等封装在一起,形成一个学生类,这个类中有学生的成员。可以通过类来实现继承与多态。
(2)类是数据类型,是一种自定义的引用类性。
(3)在一定程度上代表了现实世界中的“种类”
2.如下面的代码:
(1)
Student student=new Student ();
“=”左侧是声明了一个student对象,右侧则是创建了实例。
namespace TestClass { class Program { static void Main(string[] args) { Student student = new Student() { Id=1,Name="张安"}; Console.WriteLine("Hello World!"); } } class Student { public int Id { get; set; } public String Name { get; set; } public void Report() { Console.WriteLine($"主键: {Id},Name:{Name}"); } } }
(2)实例构造器
再看上面的截图,在这里会默认调用类的无参构造函数,对于类中的数据成员,值类型会默认为0,引用类性则默认为null
有参数的实例构造器:
类在创建实例的时候就像一个模板一样,来帮助我们创建实例,用这个模板创建出来的对象可以调用类中的数据成员与函数成员。
创建出来对象之后调用类的构造器,我们可以按照自己的想法来进行一些改变,比如下面的代码,将id与name按照自己意愿设置值。需要注意的是这一步肯定是在初始化对象给对象赋值之前,
namespace TestClass { class Program { static void Main(string[] args) { Student student = new Student(1, "构造器"); Console.WriteLine(student.Id); Console.WriteLine(student.Name); Console.ReadKey(); } } class Student { /// <summary> /// 有参数的构造函数 /// </summary> /// <param name="id"></param> /// <param name="name"></param> public Student(int id,string name) { this.Id = id; this.Name = name; }
/// <summary>
/// 静态构造器必须给静态成员赋值,而且必须是无参数
/// </summary>
static Student()
{
Amount = 100;
}
public static int Amount { get; set; } public int Id { get; set; } public String Name { get; set; } public void Report() { Console.WriteLine($"主键: {Id},Name:{Name}"); } } }
(3)实例析构器
GC是垃圾回收(Garbage Collector)的缩写。GC可以说是.NET众多机制中最为重要的,对程序员代码书写方式影响最大的机制。在CLR规范制定之初,所有机制都还在斟酌的时候,垃圾回收已经被确定会存在于.NET框架之中。
.NET的程序大部分被称为被托管的代码。托管的意义很广泛,其中重要的一点就是代码中对象内存的分配和释放是由.NET内存管理和垃圾回收机制统一管理的。和传统C++的程序员不同,C#或者其他面向.NET框架语言的程序员不再需要时刻警惕内存的泄露,因为托管对象的内存最终会被垃圾回收释放掉,尽管不同的编写方式会产生不同的运行效率。
所谓的垃圾回收,是指.NET清理托管堆上不会再被使用的对象内存,并且移动仍在被使用的对象,使它们紧靠托管堆的一边。下图展示了一次垃圾回收后托管堆上的变化。
需要注意的是当一个类调用了系统的一些底层资源,当GC收回不再使用的对象的时候,可能不会知道这个类的对象还会占用一些系统资源,所以需要我们使用析构器手动释放资源。
如下面代码,当在Main函数执行完毕之后,方法内部的student对象不会被使用了,所以此时会执行析构函数。但是注意一般情况不需要使用析构器,这会造成性能上的影响。
namespace TestClass { class Program { static void Main(string[] args) { Student student = new Student(1, "构造器"); Console.WriteLine(student.Id); Console.WriteLine(student.Name); Console.ReadKey(); } } class Student { /// <summary> /// 有参数的构造函数 /// </summary> /// <param name="id"></param> /// <param name="name"></param> public Student(int id,string name) { this.Id = id; this.Name = name; } ~Student() { Console.WriteLine("析构函数"); } public int Id { get; set; } public String Name { get; set; } public void Report() { Console.WriteLine($"主键: {Id},Name:{Name}"); } } }
(4)静态的实例构造器
静态的成员只能是由静态的构造函数来执行,Main方法中在第一次创建类对象的时候,会先调用静态构造函数,给Amount一个默认值100,然后调用对应的构造函数,具体调用的是默认的无参构造函数,还是有参数的构造函数,看具体的调用,在创建第二个对象stu的时候,只会再次调用非静态构造函数,因为在第一次调用的时候已经给静态变量Amount赋值了,
namespace TestClass { class Program { static void Main(string[] args) { Student student = new Student(1, "构造器"); Student stu = new Student(2, "构造器"); Console.WriteLine(student.Id); Console.WriteLine(student.Name); Console.WriteLine(Student.Amount); Console.ReadKey(); } } class Student { /// <summary> /// 有参数的构造函数 /// </summary> /// <param name="id"></param> /// <param name="name"></param> public Student(int id,string name) { this.Id = id; this.Name = name; Amount++; } /// <summary> /// 静态构造器必须给静态成员赋值,而且必须是无参数 /// </summary> static Student() { Amount = 100; } ~Student() { Console.WriteLine("析构函数"); } public static int Amount { get; set; } public int Id { get; set; } public String Name { get; set; } public void Report() { Console.WriteLine($"主键: {Id},Name:{Name}"); } } }
结果:
1 构造器 102