04.03 精通c# -- OOP三大支柱

就.NET平台而言,最基础的编程结构就是类类型,类是由字段数据(成员变量)以此操作这个数据的成员(构造函数、属性、方法、事件等等)所构成的自定义类型。类型的对象创建以后,就可以直接访问类的公共成员,对象这个术语表示使用new关键字创建的某个类类型的实例。对象必须使用new关键字来分配到内存中,通过new关键字把引用赋给对象之后,这个引用才会指向内存中的有效类实例。

类或结构可以通过static来定义静态成员,这样的话,这些成员就只能从类级别调用,而不是从对象引用变量进行调用。

工具类(只包含静态功能的类或结构称为工具类)是不维护任何对象级别的状态且并非由new关键字创建的类,因此,工具类会以类级别(即静态)成员公开所有功能。不需要先进行分配。

如果类定义了非静态数据(或者说实例数据),类型的每一个对象都会维护字段的独立副本。相较而言,定义类的静态数据时,同一级别的所有对象都会共享内存(分配一次)

创建新实例的时候,静态数据的值不会重置,因为CLR把数据分配到内存中只会进行一次。

构造函数,因为有些对象用户希望在使用对像之前先给对象的数据字段赋予相关的值。类可以接受任意构造函数来允许对象来允许对象在创建对象时创建状态。

静态构造函数不允许访问修饰符并不接受任何参数。无论创建了多少类型的对象,静态构造函数只会执行一次,优先执行(不允许重载)。

This关键字来提供对当前实例的访问(自定义构造函数是可以解决传入参数和字段名称同名时造成的作用域歧义)。

封装:这是将对象用户不必了解的实现细节隐藏起来的一种语言能力(隐藏一个对象的实现并且保护数据的完整性)。

和封装编程紧密相关的概念是数据保护的概念,因为公共的数据点很容易破坏。

继承:指基于已有的类定义来创建新类定义的语言能力。通过继承,子类可以继承基类(父类)的核心功能,并且扩展基类的行为(促进代码重用)。“is-a”关系

多态:表示的是语言以同一种方式处理相关对象的能力。准确的说,这个面向对象语言的原则允许基类为所有派生类定义一个成员集合(多态接口),一个类类型的多态接口由任意个虚拟(virtual)或抽象(abstract)成员组成(同样的方式处理相关对象或者说相关类型如何对相同的请求做出不同的响应)。

虚拟成员是定义默认实现的基类中的成员,他可能被派生类改变(重写),而抽象方法是基类中不提供默认实现的成员,但抽象方法必须被派生类重写。当派生类重写有基类定义的成员时,其实就重定义了响应相同请求的方式。

对象的内部数据不应该从对象实例直接访问,对象数据应该被定义为私有的,如果调用者想改变队形的状态,就要间接的使用公共成员。(表示对象状态的类成员都不应该被标记为公共的)

C#倾向于使用属性来封装数据,好处在于对象的使用者可以使用单个命名的项来控制内部数据点。

在新建对象时可以通过构造函数指定初始值,而属性允许我们安全的获取或设置实际的数据。

coust类的常量字段是隐式静态的,定义常量时必须指定初始值,和readonly只读字段不一样,需要编译时就要知道,而只读字段(不是隐式静态的)是可以在运行是决定,可以在构造函数赋值。常量不可以。(永不改变的数据点)

封装,如何使用构造函数和各种成员(构造函数、字段、属性、方法、只读字段等)来构建一个定义明确的类类型。

继承,可以促进代码重用,基本思想是新的类可以利用既有类的功能。继承保护了封装,不能通过对象引用来访问私有成员。

.NET平台允许某一个类(或结构)类型实现许多独立的接口。这样,c#类型可以实现很多行为,有避免了多重继承的复杂性,一个类只允许一个直接基类,但一个接口可以直接从多个接口派生。

Sealed 密封类,用于类类型来来防止其他类型通过继承扩展其行为。

C#结构总是隐式密封的,我们不可以从结构继承结构,从类继承机构或从结构继承类,结构只能独立建模。

基类用于定义所有派生类共有的特性,子类通过增加特定的行为来扩展这些一般功能。

包含/委托(聚合)就是增加公共成员到包含类,以便使用被包含对象的功能。(可能是把类作为新类的字段使用???)

多态为子类定义了一种方式,使其可以定义由其基类定义的方法。这种方法叫重写。(virtual、override),被override标记的方法叫虚方法。当不使用override而使用new时就会隐藏任何此类之上的该方法的实现。

Abstract 抽象类,定义了却不能直接创建它(实例化),但它们包含了派生类型中所有的通用数据和功能,我们可以用抽象基类变量来保存任何指向任何子类的引用。使用抽象,我们可以为那些不是具体实体的东西建模。我们不能直接实例化抽象类,但是在创建派生类时,会在内存中对其进行组装。定义若干在分配派生类时间接调用的构造函数是很正常的。

如果类被定义为抽象基类,他就可以定义许多抽象成员。当你希望定义没有提供默认实现而不需在每个派生类中实现的成员时,就可以使用抽象成员。这样强调了每一个后代具有多态接口,他们需要自己处理抽象方法的细节。,可以构建高度灵活的应用程序。使用抽象基类变量来保存指向任何子类的引用。

多态:允许子类型指针赋值给父类型的指针,也就是同一操作作用于不同的对象,有不同的解释,产生不同的结果。

作用:把不同的子类当作父类看,屏蔽不同子类的差异,以通用的代码适应不断变化的需求。

类类型之间的强制转换的第一条准则就是如果两个类通过“is-a”关系关联,在基类引用中保存派生类型总是安全的 “基类 实例名=new 派生类”,这是隐式转换,因为基于继承的规则。第二条规则是强制装换操作符进行显示的向下转换(显式强制转换在运行时而不是在编译时进行运算,编译可能通过,但可能会发生运行时异常)。

As在转换时可以用来判断是否能够兼容(例:aa a=(aa)bb可以写作aa a=bb as aa,当不兼容时,a的职为null)。

Is关键字有着和as一样的作用,但是is不兼容会返回false(例:if(bb is aa){};)。

Equals()的默认行为用来测试两个变量是不是指向内存中的同一对象,但是对string类型时被重写了,用于判断两个值的内容。


分享到:


相關文章: