C#随记04
面向对象程序设计
将数据和对数据的操作看作是一个不可分割的整体,力求将现实问题简单化。尽量复合人们的思维习惯,提高软件的开发效率,并方便后期的维护。
- 对象具有唯一性
- 对象之间各不相同,每一个对象都有自己的运动规律和内部状态
- 对象与对象之间又是可以相互联系,相互作用的
面向对象技术是一种从组织结构上模拟客观世界的方法
对象
对象是事物存在的实体。
- 静态部分
不能动的部分,属性。 - 动态部分
所具备的行为。 - 特征:
- 每一个对象必须有一个名字以区别其他对象
- 用属性来描述对象的某些特征
- 有一组操作,每一个操作决定对象的一种行为
- 对象的操作可以分为两类,一类是自身所承受的操作,一类是施加于其他对象的操作。
- 属性
- 行为
类
同一事物的统称,创建对象时所依赖的规范
封装对象属性和行为的载体
三大基本特征
封装
将对象的属性和行为封装起来,而将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。
- 采用封装思想保证了类内部数据结构的完整性,使用该类的用户不能直接看到类中的数据结构,而只能执行类中允许公开的数据。这样就避免了外部对内部数据的影响,提高了程序的可维护性。
继承
实现重复利用的重要手段,子类通过继承复用了父类的属性和行为的同时,又添加了子类特有的属性和行为。
多态
将父类对象应用于子类的特征就是多态。
龙生九子,九子都有龙的特征,同时又有自己的独特特征。
- 类时一种数据结构,它可以包含数据成员(常量和变量)、函数成员(方法、属性、构造函数和解构造函数等)和嵌套类型。
类的声明
class 类名{
}
类的成员
字段、属性、方法、构造函数等
字段
常量或变量
属性
- 属性是对现实实体特征的抽象,提供对类或对象的访问。
- 类的属性描述是状态信息,在类的实例中,属性的值表达对象的状态值。
- 属性具有访问器,这些访问器指定在它们的值被读取或写入时需要执行的语句,因此属性提供一种机制,把读取和写入对象的某些特征与一些操作关联起来,开发人员可以像使用公共数据成员一样舒勇属性。
[权限修饰符][类型][属性名]{
get{get访问器体}
set{set访问器体}
}
- 修饰符:指定属性的访问级别
- 类型:指定属性的类型,可以是任何预定义或自定义类型
- 属性名:一种标识符,首字母通常大写
- get访问器:相当于一个具有属性类型返回值的无参数方法,它除了作为赋值的目标外,当表达式中引用属性时,将调用该属性的get访问器获取属性的值,get访问器需要用return语句来返回,并且所有的return语句都必须返回一个可隐式转换为属性类型的表达式。
- set访问器:相当于一个具有单个属性类型值参数和void返回类型的方法。set访问器的隐式参数始终命名为value,当一个属性作为赋值的目标被引用时,就会调用set访问器,所传递的参数将提供新值。由于set访问器存在隐式的参数value,因此,在set访问器中不能自定义名称为value的局部变量或常量。
根据是否存在get和set访问器,可以将属性分为: - 可读可写属性:包含get和set
- 只读属性:只包含get
- 只写属性:只包含set
属性的主要用途是弦值外部类对类中成员的访问权限,定义在类级别上。
自定义一个类,要求该属性为可读写属性,并设置其访问级别为public
private string tradecode="";
public sting tradcode{
get{return tradecode;}
set{tradecode=value;}
}
由于属性的set访问器中可以包含大量的语句,因此可以对赋予的值进行检查,如果值不安全或不符合要求,就可以进行处理操作,这样可以避免因为给属性设置了错误的值而导致的异常。
通过属性控制年龄的输入范围
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace studyDaily
{
class Program
{
private int age;//定义字段
public int Age //定义属性
{
get
{
return age;
}
set
{
if (value > 0 && value < 70)
{
age = value;
}
else
{
Console.WriteLine("输入的数据不合理!");
}
}
}
static void Main(string[] args)
{
Program p = new Program();
while (true)
{
Console.Write("请输入年龄:");
p.Age = Convert.ToInt16(Console.ReadLine());//为年龄赋值
}
}
}
}
构造函数
在创建对象时执行的方法,构造函数具有与类相同的名称,它通常用来初始化对象的数据成员:
- 构造函数没有返回值
- 构造函数的名称要与本类的名称相同
public class Book{
public Book(){//无参数构造方法
}
public Book(int args){//有参数构造方法
args=2+3;
}
}
默认构造函数和有参数构造函数
在定义类时,如果没有定义构造函数,编译器会自动创建一个不带参数的默认构造函数
class Book{
}
创建Book类对象
Book book=new Book();
如果在定义类时定义了含有参数的构造函数,还想要使用默认构造函数,就需要进行显式定义
静态构造函数
可以为类定义静态构造函数,这种构造函数只执行一次。
编写静态构造函数的主要原因是,类有一些静态字段或者属性,需要在第一次使用类之前,从外部源中初始化这些静态字段和属性。
定义静态构造函数时,不能设置访问修饰符,因为其他代码从来不会调用它,它只在引用类之前执行一次,另外,静态构造函数不能带任何参数,而且是一个类中只能有一个静态构造函数,它只能访问类的静态成员,不能访问实例成员。
static Program(){
Console.WriteLine("static");
}
在类中,静态构造函数和无参数的实例构造函数是可以共存的,因为静态构造函数是在加载类时执行,而实例构造函数是在创建类的对象时执行。
析构函数
析构函数主要用来释放对象资源。.net Framework类库有垃圾回收功能,当某个类的实例被认为是不再有效,并符合析构条件时,.net Framework类库的垃圾回收功能就会调用该类的析构函数实现垃圾回收。析构函数是以类名前加前缀“~”来命名的。
~Program(){
Console.WriteLine("析构函数自动调用");
}
析构函数式自动调用的,不需要显式定义,如果需要定义,一个类中只能定义一个析构函数。
- 构造函数和析构函数主要用来对对象进行初始化和释放对象资源。
- 对象的生命周期从构造函数开始,以析构函数结束
权限修饰符
- private:所有类或者成员 只能在本类中访问
- protected:类和内嵌类的所有成员 在本类和子类中访问
- internal:类和内嵌类的所有成员 在同一程序集中访问
- protected internal:类和内嵌类的所有成员 在同一程序集和子类中访问
- public:所有类或者成员 任何代码都可以访问
定义类时只能使用public和internal权限修饰符,这取决于是否希望在包含类的程序集外部访问它