面向对象的几个重要概念总结分析

一、面向过程与面向对象

   (1)面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

       面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

   (2)例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用分别的函数来实现,问题就解决了。

       而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为 1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的i变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

       可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了总多步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。功能上的统一保证了面向对象设计的可扩展性。

       比如我要加入悔棋的功能,如果要改动面向过程的设计,那么从输入到判断到显示这一连串的步骤都要改动,甚至步骤之间的循序都要进行大规模调整。如果是面向对象的话,只用改动棋盘对象就行了,棋盘系统保存了黑白双方的棋谱,简单回溯就可以了,而显示和规则判断则不用顾及,同时整个对对象功能的调用顺序都没有变化,改动只是局部的。

       再比如我要把这个五子棋游戏改为围棋游戏,如果你是面向过程设计,那么五子棋的规则就分布在了你的程序的每一个角落,要改动还不如重写。但是如果你当初就是面向对象的设计,那么你只用改动规则对象就可以了,五子棋和围棋的区别不就是规则吗?(当然棋盘大小好像也不一样,但是你会觉得这是一个难题吗?直接在棋盘对象中进行一番小改动就可以了。)而下棋的大致步骤从面向对象的角度来看没有任何变化。

二、类

(1) 在面向对象的程序设计语言中,类是对一类“事物”的属性与行为的抽象。

举一个浅显的例子。Person(人)是对地球上所有具有特殊智能的生物包括你,我,他,张三,李四等的抽象。
“你”,“我”,“他”,“张三”,“李四”等等都属于“人”这一类所包含的个体。

(2) 类和对象的区别
1,类是一个抽象的概念,它不存在于现实中的时间/空间里,类只是为所有的对象定义了抽象的属性与行为。就好像“Person(人)”这个类,它虽然可以包含很多个体,但它本身不存在于现实世界上。
2,对象是类的一个具体。它是一个实实在在存在的东西
3,类是一个静态的概念,类本身不携带任何数据。当没有为类创建任何对象时,类本身不存在于内存空间中
4,对象是一个动态的概念。每一个对象都存在着有别于其它对象的属于自己的独特的属性和行为。对象的属性可以随着它自己的行为而发生改变。

面向对象的三大特性:

三、封装

封装:隐藏对象的属性和实现细节,仅对外提供访问方式

封装的目的是增强安全性和简化编程,使使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员。

优点:
  1、将变化隔离
  2、便于使用
  3、提高重用性
  4、提高安全性
封装原则:
  1、将不需要对外提供的内容都隐藏起来。
  2、把属性都隐藏,提供公共方法对其访问

四、继承

(1) 继承的定义:

1、在一个类基础上定义一个新类叫继承,原有的类叫父类,新生成的类叫子类。

2、一个父类可以有多个子类,一个子类只能有一个父类。


(2) 继承的特点:

1、子类拥有父类的属性和方法

2、子类可以有自己新的属性和方法

3、子类可以重写(覆盖)父类的方法

4、可以声明父类,创建子类


声明的什么类型,就只能调用本类型的属性和方法

创建的什么类型,运行什么类型的方法

创建的什么类型,就可以强转为什么类型

五、多态

几种重要概念的区别

 

重载与覆盖
 1.方法的覆盖是子类和父类之间的关系;方法的重载是同一个类中方法之间的关系
 2.覆盖只能由一个方法,或只能由一对方法产生关系;方法的重载是多个方法之间的关系。
 3.覆盖要求参数列表相同;重载要求参数列表不同。
 4.覆盖关系中,调用那个方法体,是根据对象的类型(对像对应存储空间类型)来决定;重载关系,是根据调用时的实参表与形参表来选择方法体的。

 

接口与抽象类

 1.两者表达的概念不一样。抽象类是一类事物的高度聚合,那么对于继承抽象类的子类来说,对于抽象类来说,属于“是”的关系;而接口是定义行为规范,因此对于实现接口的子类来说,相对于接口来说,是“行为需要按照接口来完成”。

 ex:举个例子。例如,狗是对于所有狗类动物的统称,京哈是狗,牧羊犬是狗,那么狗的一般特性,都会在京哈,牧羊犬中找到,那么狗相对于京哈和牧羊犬来说,就属于这类事物的抽象类型;而对于“叫”这个动作来说,狗可以叫,鸟也可以叫。很明显,前者相当于所说的是抽象类,而后者指的就是接口。

 2.抽象类在定义类型方法的时候,可以给出方法的实现部分,也可以不给出;而对于接口来说,其中所定义的方法都不能给出实现部分。

 3.继承类对于两者所涉及方法的实现是不同的。继承类对于抽象类所定义的抽象方法,可以不用重写,也就是说,可以延用抽象类的方法;而对于接口类所定义的方法或者属性来说,在继承类中必须要给出相应的方法和属性实现。
 4.在抽象类中,新增一个方法的话,继承类中可以不用作任何处理;而对于接口来说,则需要修改继承类,提供新定义的方法。

结构与类

 1.结构是一个值类型,而类是引用类型。在内部系统中,结构源于System.ValueType

 2.结构不能用于继承。一个结构不能继承自一个类或另一个结构;一个类也不能继承自一个结构

 3.结构默认包含一个无参数的、默认的构造器,他不做任何事。你可以多次重载他们,但不能添加一个无参数的构造函数。

 4.虽然结构非常强大,但是他们主要是作为数据的容器使用,而不是一个功能齐全的对象。因为他们是值类型(不是存储在栈中),传递他们非常快。MSDN中指出,少于16字节的数据,用结构进行处理的效率要高于类。

5、值类型与引用类型
 

结构是值类型,值类型在堆栈上分配地址,所有的基类型都是结构类型(例如:int 对应System.int32 结构,string 对应 system.string 结构 ,通过使用结构可以创建

更多的值类型);类是引用类型:引用类型在堆上分配地址,堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。所以结构处理

作为基类型对待的小对象,而类处理某个商业逻辑。
 

因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋值只是复制引用
注:(1)虽然结构与类的类型不一样,可是他们的基类型都是对象(object),c#中所有类型的基类型都是object。(2)虽然结构的初始化也使用了New 操作符可是结构对象

依然分配在堆栈上而不是堆上,如果不使用“新建”(new),那么在初始化所有字段之前,字段将保持未赋值状态,且对象不可用。
 

6、继承性

结构不能从另外一个结构或者类继承,本身也不能被继承,虽然结构没有明确的用sealed声明,可是结构是隐式的sealed;类完全可扩展的,除非显示的声明sealed 否则

类可以继承其他类和接口,自身也能被继承。
注:虽然结构不能被继承 可是结构能够继承接口,方法和类继承接口一样

例如:结构实现接口
interface IImage

{

       void Paint();

}


struct Picture : IImage

{

       public void Paint()

           {

               // painting code goes here

           }

 

           private int x, y, z;  // other struct members

}


7、内部结构:
 

结构没有默认的构造函数,但是可以添加构造函数,没有析构函数,没有 abstract 和 sealed(因为不能继承),不能有protected 修饰符,可以不使用new 初始化,在结

构中初始化实例字段是错误的;类有默认的构造函数,有析构函数,可以使用 abstract 和 sealed,有protected 修饰符,必须使用new 初始化。
 

8、如何选择结构还是类
 

讨论了结构与类的相同之处和差别之后,下面讨论如何选择使用结构还是类:
(1)、堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些
(2)、 结构表示如点、矩形和颜色这样的轻量对象,例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低


(3)、在表现抽象和多级别的对象层次时,类是最好的选择
(4)、大多数情况下该类型只是一些数据时,结构时最佳的选择

 

Virtual方法与Abstract方法

1.Virtual方法(虚方法)
 
virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况:
 
情况(1):在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。
情况(2):在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。
 
2.Abstract方法(抽象方法)

abstract关键字只能用在抽象类中修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现。

 

C#中静态与非静态方法比较

C#的类中可以包含两种方法:C#静态方法与非静态方法。那么他们的定义有什么不同呢?他们在使用上会有什么不同呢?
 
最直观的差别:使用了static 修饰符的方法为静态方法,反之则是非静态方法。

1.C#静态方法与非静态方法比较一、
C#静态成员:
(1)静态成员属于类所有,非静态成员属于类的实例所有。
(2)每创建一个类的实例,都会在内存中为非静态成员新分配一块存储;

静态成员属于类所有,为各个类的实例所公用,无论类创建了多少实例,类的静态成员在内存中只占同一块区域。

2.C#静态方法与非静态方法比较二、
C#静态方法
(1)C#静态方法属于类所有,类实例化前即可使用。
(2)非静态方法可以访问类中的任何成员,静态方法只能访问类中的静态成员。
(3)因为静态方法在类实例化前就可以使用,而类中的非静态变量必须在实例化之后才能分配内存,

这样,C#静态方法调用时无法判断非静态变量使用的内存地址。所以无法使用。而静态变量的地址对类来说是固定的,故可以使用。

3.C#静态方法与非静态方法比较三、
C#静态方法是一种特殊的成员方法 它不属于类的某一个具体的实例,而是属于类本身。所以对静态方法不需要首先创建一个类的实例,而是采用类名.静态方法的格式 。
(1)static方法是类中的一个成员方法,属于整个类,即不用创建任何对象也可以直接调用!
static内部只能出现static变量和其他static方法!而且static方法中还不能使用this....等关键字..因为它是属于整个类!
(2)静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁。
(3)静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存.
(4)C#中的方法有两种:实例方法,静态方法.

Typeof()与GetType的区别

Typeof()是运算符而GetType是方法
GetType()是基类System.Object的方法,因此只有建立一个实例之后才能够被调用(初始化以后)
Typeof()的参数只能是int,string,String,自定义类型,且不能是实例
 

GetType() 和typeof()都返回System.Type的引用。
 

TypeOf() 和GetType()的区别:  

(1)TypeOf():得到一个Class的Type

(2)GetType():得到一个Class的实例的Type

override 一个方法的前担是这个方法在父类中:abstract or  virtual, override

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值