好的OOP程序--->模块合理、结构清晰、程序规范、注释明确、运行流畅、维护容易、扩展方法。
OOP是学习各种编程的原则、方法、技巧、经验、模式、架构等。
所有面向对象的编程语言,都是把我们要处理的"数据"和"行为"封装到类中。
1、设计类
2、关联类
3、使用类
类的基本组成与对象
1、类名定义:名词,要求首字母大写,避免单词缩写
2、字段和属性,用来描述这个对象的静态信息(数据存储)
3、方法和接口,用来说明这个对象的行为特征(方法操作)
访问修饰符 class 类名
{
//定义字段部分
字段1的类型 字段1
字段2的类型 字段2
...
//定义属性部分
属性1的类型 属性1
属性2的类型 属性2
...
//定义方法部分
方法1
方法2
...
}
总结1:一个类其实就是相关数据和特定方法"结构的封装"
类 对象名 = new 类();
总结2:对象是按照类创建的一个具有"特定数据的实例",通过对象调用类所封装的数据和方法!
访问修饰符
1、类的访问修饰符
作用:限制这个类可被使用的范围
类型:只有俩个(public和internal)
2、类成员访问修饰符
作用:限制类的字段、属性、方法的可访问范围
类型:private(私有的,仅供类的内部使用)、public(公有的,可以通过对象从外面使用)
注意:方法内部的变量,称为:"局部变量"是没有访问修饰符的
类的属性(Property)
1、属性的使用
作用:在OOP中主要用来封装数据
要求:一般采用Pascal命名法,数据类型和字段要一致,使用public修饰。
读取:属性通过get方法,返回私有字段的值。
赋值:属性通过set方法,借助于value给私有字段赋值
本质:属性本身是没有保存数据的,字段才是数据的存储单元。属性的本质是方法
2、属性的定义
private int courseId;//返回私有字段的值
public int CourseId
{
get{return courseId;}
//通过value给私有字段赋值
set{courseId = value;}//C#3.0以后使用自动属性public int CourseId{get;set;}
}
- 属性特性
- 扩展业务逻辑
在属性get和set方法中添加业务逻辑,从而有效避免非法数据,示例:
cs
Private int courseId = 0;
Public int CourseId
{
get{return courseId;}
set
{
if(value<0)
courseId = 1000;
else
courseId = value;
}
}
2.控制读写操作
根据需求设置为只读属性
//只读属性1,直接去掉set方法,可以在定义的时候初始化
Public string CoureName {get;} = ".Net";
//只读属性2,直接去掉set方法,并在get中添加业务逻辑
Public string CourseInfo
{
Get{return $"课程名称:{CourseName}课程编号:{courseId}课程价格:{UnitPrice}";}
}
属性和字段的总结
- 字段(成员变量):
- 内容使用:字段主要是为类的内部数据交换使用,字段一般是private。
- 数据存储:字段只是用来存储数据,如果不是静态字段,生命周期和对象共存亡。
- 读写不限:我们可以给字段赋值,也可以获取字段的值(非常常用)(readonly除外)
- 属性(字段封装)
- 外部使用:属性一般是向外提供数据访问,属性是public修饰,用来对外表示对象的静态特征。
- 业务扩展:属性内部可以添加我们需要的业务逻辑,可以避免非法数据,或完成其他相关任务。
- 读写可控:属性可以根据需要设置为只读属性,更好的体现面向对象的"封装特性"!也就是安全性。
- 使用
- 常规化使用:对象本身的"对外"数据保存,都是通过属性完成的,调用者都可以使用。
- 强制性使用:公有化字段,在很多时候是无法被解析的。(比如dgv、combobox的显示问题)
方法
- 概念:方法表示这个对象能够做什么,也就是封装了这个对象行为。
- 类型:实例方法------》静态方法------》(抽象方法、虚方法)------》特殊的:构造方法(对象创建的时候使用)
构造方法的使用:
- 作用:构造方法是在对象创建的时候被调用的,所以,在创建对象的时候可以完成一些初始化的任务。
初始化:包括给对象的属性赋值,或从其他对象、文本等获取基础数据。
一个类中,如果没有显示的写出任何构造方法,编译器会默认生成一个无参数的构造方法
可以随时显示的添加一个无参数的构造方法,构造方法无返回值
- 构造方法的类型
- 无参数构造方法:通常是用来直接初始化对象的属性或"某些不变的数据"。
cs
Public void Dowork1()
{
//创建对象,得到类的实例,Course()就是无参数的构造方法
Course course = new Course();
//给对象的字段赋值
course.Courseld = 1;
course.CourseldName = ".Net全栈";
//获取对象的数据
Console.WriteLine(course.Type);
//调用对象的方法
string info = course.ShowCourseInfo();
Console.WriteLine(info);
}
-
- 有参数的构造方法:让对象创建者,自己传递要初始化的相关数据。
cs
//有参数的构造方法
public void Dowork2()
{
//有参数的构造方法
Course course2 = new Course(1,".Net","编程");
Console.WriteLine("有三个参数构造方法" + course2.ShowCourseinfo());
}
public void Dowork3()
{
//俩个参数的构造方法
Course course3 = new Course(2, ".Net");
Console.WriteLine("俩个参数的构造方法 "+"Name="+course3.CourseName+";ID="+course3.CourseId);
}
代码实例:
cs
public class Course
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public string Type { get; set; }
public string ShowCourseinfo()
{
return $"课程名称:{CourseName},课程编号:{CourseId},课程系列:{Type}";
}
//无参数的构造方法
public Course()
{
CourseId = 100;
CourseName = ".Net";
Type = "编程";
//在这里还可以编写读取相关文件或者从其他数据读取的方法或逻辑...
}
//有参数的构造方法
public Course(int courseId, string courseName)
{
//this后面不可能接局部变量,只能接成员变量、属性、方法
this.CourseId = courseId;
this.CourseName = courseName;
}
//this代表在当前构造方法之间调用,base调用父类构造方法
public Course(int courseId, string courseName, string type) : this(courseId, courseName)
{
Type = type;
}
}
class TestClass4
{
//无参数的构造方法
public void Dowork1()
{
//无参数构造方法
Course course = new Course();
Console.WriteLine("无参数构造方法"+course.ShowCourseinfo());
}
//有参数的构造方法
public void Dowork2()
{
//有参数的构造方法
Course course2 = new Course(1,".Net","编程");
Console.WriteLine("有三个参数构造方法" + course2.ShowCourseinfo());
}
public void Dowork3()
{
//俩个参数的构造方法
Course course3 = new Course(2, ".Net");
Console.WriteLine("俩个参数的构造方法"+"Name="+course3.CourseName+";ID="+course3.CourseId);
}
}
对象初始化器的使用
- 引入:C#3.0时代开始
- 作用:更加灵活的初始化对象的"属性",可以在创建对象的同时为对象的属性赋值,而无需显式调用构造函数并逐个赋值属性。
代码实例:
cs
public void Dowork4()
{
Course course = new Course()
{
CourseName = ".Net",
};
Console.WriteLine(course.CourseName);
}
构造方法和对象初始化器总结:
- 构造方法:
- 存在的必要性:一个类中,至少要有一个构造方法。(可以是无参数的,也可以是有参数的)
- 调用的特殊性:只能在对象创建的时候,通过new关键字调用。
- 使用的强制性:对象的创建,必须调用指定的构造方法,也就是参数必须统一
- 语法的特殊性:不能有返回值、构造方法名称必须和类名一样!
- 构造方法PK对象初始化器
- 相同点:都可以完成对象"属性"初始化
- 不同点:
- 有无强制性:构造方法有强制性,对象初始化器没有强制性,随意使用。
- 使用的范围:对象初始化器只能完成属性初始化,而构造方法可以完成任何我们需要的初始化任务。
- 使用的位置:对象初始化器在创建对象的时候使用,而构造方法必须提前写在类中。
- 出现的时间:构造方法在.Net1.0版本就有,而对象初始化器只能在.Net3.0以上版本才能使用。
成员变量和局部变量同名时:
- 成员变量和局部变量同名时,一般是就近原则取变量,如果我们需要舍近求远,则必须添加this。
对象的销毁:
- 对象的生存周期:
- 对象在内存中不断的"生生死死",具有生命周期。
- 对象在内存中的状态:
- 正在引用:程序正在使用的对象
- 游离状态:没有引用的对象,已经使用完毕但依然占据空间
- 垃圾回收机制(GC)
- .Net虚拟机特有的机制,自动运行,并检查对象的状态。
- 发现对象不被引用时,会释放其所占空间(销毁)
析构函数:
1、C++中析构函数的使用,当使用delete关键字删除对象时,析构函数会自动调用
cs
~类名()
{
}
2、托管运行环境下对象的销毁由虚拟机负责,析构函数没多大用途。