面向对象基础

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

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

对象

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

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

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

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

实例

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

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

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

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

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

构造函数

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

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

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

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

析构函数

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

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

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

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

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

属性

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

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

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

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

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

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

封装

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

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

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

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

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

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

继承

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

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

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

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

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

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

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

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

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

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

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

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

多态

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

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

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

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

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

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

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

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

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

抽象类

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

其不能被实例化,

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

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

接口

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

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

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

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

image

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

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

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

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

image 

image

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

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

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

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

image

下面就开始来写类了

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

image

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

先是 Fly 接口

image

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

image

image

接口 Quack 即叫声部分的代码

image

实现了 Quack 接口的三个类

image

image

image

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

image

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

image

image

image

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

image

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

下面在给出效果吧

image

 

posted @ 2010-05-01 16:32  小宝马的爸爸  阅读(986)  评论(0编辑  收藏  举报