您的位置:首页 > 其它

面向对象基础

2011-01-02 17:58 134 查看
转自——Zachary.XiaoZhen - 梦想的家园

面向对象中最常提到的就是对象,类,实例这些,

既然是面向对象的话,那先从对象谈起,

对象

首先,一切事物皆为对象,对象是一个实体,其可以包含自己的特性和特定的行为。



就是将一些对象所具有的相同属性和相同的行为进行提取出来,也就是抽象,

提取出来后便会组成一个集合,那么这个集合就是类,

所以类,也可以理解为是对类似的对象分类的意思。

实例

就是一个真实的对象,由于前面使用类来对对象进行了分类,提取了他们相似的属性和行为,

所以,其满足于这个类,也就是可以通过这个类来生成对应的实例,这就是所谓的实例化,

比如,一个人可以用一个类来描述,这个类应该有头发颜色,肤色,身高等等这样的属性,

然后还会有如走路,吃饭这样的行为,那么,便可以通过 new 这个人类来生成一个实例,

这就是实例化一个人类的实例。

构造函数

构造函数是用来对类实现初始化的,其没有返回值,在通过 new 一个实例的时候自动调用构造函数

需要提及的是,任何一个类都有构造函数,如果没有自定义构造函数的话,

系统会调用默认的构造函数来实现实例化对象,当然,如果自定义了构造函数的话,

那么系统默认的构造函数就失效了。

析构函数

一个类中只能有一个析构函数,且析构函数无法被继承和重载,

同时,无法使用程序调用析构函数,因为析构函数是自动被调用的,也就是程序员是无法控制何时调用析构函数的,

因为这是由垃圾回收器决定的,垃圾回收器检查是否存在应用程序不再使用的对象,

如果垃圾回收器认为某个对象符合析构,则调用析构函数,并且回收内存,

当程序退出时也会调用析构函数来回收内存。

属性

属性是一个方法或一对方法,但是在访问它的代码来看,它却是一个字段,而不是一个方法,

比如,在调用方法时,一般都是 . FunctionName(),而在访问字段时确是 . FieldName,

属性有两个方法,一个是用来设置值的 set(),一个是用来获取值的 get(),

可以通过这两个方法来实现对一个字段的访问控制,

比如只读控制(即只有 get 方法),

只写控制(即只有 set 方法)或者是可读可写(既有 set 方法,又有 get 方法)。

封装

每一个对象都包含了它能进行操作所需要的所有的信息,

所以,一个对象不必依赖其他对象来完成自己的操作,

这里的意思就是一个对象是可以独立存在的,

比如,一只狗,它可以将自己的名字,重量等信息封装起来,

这样这只狗便是一个完整的对象,是可以独立存在的,而不必依赖其他的动物。

封装的优点体现在:良好的封装是可以减少耦合的,类内部的实现是独立的,类具有清晰地对外接口。

继承

继承就是一种“是一个”的关系,也就是说,一个对象是另外一个对象的一部分,

如果单就功能来说的话,继承也可以理解为是功能上的扩展,比如原来的类的功能只是走路,

那么我可以通过继承原来的类,然后再在这个子类中添加一个跑步的类,这样就实现了功能的扩展,

也就是子类可以完成包括父类所有的功能在内的更多功能。

子类既然继承了父类,那么子类便继承了父类中的方法,字段,属性,事件,索引器等,

但是其中有一个是例外的,就是构造函数是不能被继承的,其只能被子类调用,而不能继承。

继承的优点体现在:修改和复用方便,代码得到共享,同时对扩展也是比较方便的,

但是继承滥用会出现一系列的问题:这是因为继承破坏了封装性,

从上面的继承关系来看,父类的非私有成员在子类中是可以完全访问的,

这样便增大了两个类之间的耦合度(继承是一种类与类之间的强耦合关系)。

然后,继承还有一个最大的缺点,那就是只要是父类改变了,

那么子类不得不变(因为其完全继承了父类)。

多态

多态表示的是不同的对象可以执行相同的动作,但要通过他们自己的实现代码来执行。

换句话说就是子类可以以父类的身份出现,但是在动态运行时,其执行的却是自己的代码,

但是需要注意的是,当子类以父类的身份出现时,子类中特有的属性和方法是便可以使用的。

为了使子类的实例完全接替来自父类的类成员,父类必须将该成员声明为虚拟的,

这个可以通过关键字 Virtual 来实现,然后,子类可以通过使用 override 关键字来重写父类中定义的方法,

也就是以自己的方式来实现父类中定义的方法。

多态的原理是当方法被调用时,无论对象是否被转换为其父类,

都只有位于对象继承链最末端的方法实现会被调用,

也就是说,虚方法是按照其运行时类型而非编译时类型进行动态绑定调用的。

抽象类

C# 中是可以使用抽象类和抽象方法的,抽象类有如下的特定:

其不能被实例化,

抽象类中定义的抽象方法必须在其子类重写,

只要是类中包含了一个及以上的抽象方法,那么这个类就是抽象类,必须用 abstract 描述类

接口

接口呢,是一个功能集合,一旦类实现了接口,类就可以支持接口所指定的所有属性和成员,

在声明接口时,是不允许提供接口中任何成员的执行方式的,所以接口是不能实例化的,并且不能有修饰符。

如果一个类实现了一个接口,那么这个类就必须要实现接口中的所有的方法和属性。

下面呢就是通过一个整体的 Demo 来实现上面的关于面向对象的基础部分的演练:





上面的例子中呢,有 Duck(鸭子这个抽象类),然后其下面有三个子类,

分别是天鹅(Swan),笨鸭(FoolDuck),玩具鸭(ToyDuck),

所有的鸭子都是会游泳的,所以直接把 Swim()方法写在了父类 Duck 中,

这样所有继承自 Duck 类的子类均会游泳了,因为都会有 Swim()这个方法。









然后,还定义了两个接口,一个是 Fly(也就是能不能飞行),还有一个就是 Quack(即能不能发出发出叫声),

然后定义了两个类来实现接口 Fly ,两个类的行为分别是能够飞和不能够飞,

然后就是定义了三个类来实现接口 Quack ,这三个类分别代表发出 GuaGua 声音,和发出 ZhiZhi 声音,

还有一个就是不会发出声音了。





下面就开始来写类了

首先,完成后的项目架构为





下面就来一个一个的看代码了

先是 Fly 接口





然后是实现了这个接口的两个类 CanFly 和 FlyNoWay









接口 Quack 即叫声部分的代码





实现了 Quack 接口的三个类













然后就是来看核心的 Duck 类了





最后就是继承自 Duck 类的三个子类了













再来看一下客户端的代码吧





上面就是整个 Demo 的所有代码了,

下面在给出效果吧



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: