【C#】——面向对象思想

来源:互联网 发布:怪物猎人ol数据互通 编辑:程序博客网 时间:2024/06/06 16:37

       C#这个东西听说时还是当时自己学C语言的时候,那时甚至都不知道什么叫C++,什么叫Java。更别说是面向对象的思想了。之前学到的都是面向过程的技术,实现一个功能要一点一点去理清逻辑,然后才能勉强的写出来。后来学了VB才开始明白一点什么是面向对象。那么C#是一种什么样的语言呢?下面还是用官方一点的语言来解释下:

       C#是微软公司发布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言。它是一种安全的、稳定的、简单的、优雅的,由C和C++衍生出来的面向对象的编程语言。它在继承C和C++强大功能的同时去掉了一些它们的复杂特性(例如没有宏以及不允许多重继承)。C#综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程的支持成为.NET开发的首选语言。

       自以为学过一点C语言和C++的我理解起来会比较容易,但这个过程也是感到有很多的困惑,还需要继续探索。下面介绍一下面向对象的主要技术。

       一、类与对象

       所谓的就是具有相同的属性和功能的对象的抽象的集合,而对象就是类的一个实例化,可以把类比作设计师设计出来的蓝图,也可以说是一个模板,它规定了对象具有哪些特征,而对象是根据蓝图生产出来的产品。如果把建筑设计出来的图纸比作类,那盖出来的楼房就是一个一个的对象。

       在实例化对象的时候会用到一个关键字:new,这个看似小小的一个实例化对象,里面却蕴含着很多的东西。下面简单的介绍一下, 说一下new的过程是如何进行的。

       首先,new当做运算符的时候,用于在堆上创建对象和调用构造函数。

       以Vehicle veh1=new Vehicle()为例。通常咱们都把类似于这样的语句称为创建一个对象,也就是实例化。其实它包括了四个动作,缺一不可。

       1、“Vehicle veh1”创建了一个Vehicle类的引用变量veh1,所谓Vehicle类引用就是以后可以用来指向所创建的对象的。

       2、“new Vehicle”是以Vehicle类为模板,在堆空间里创建一个对象并分配内存。

       3、末尾的”()“意味着对象创建后,立即调用Vehicle类的构造函数,对刚生成的对象进行初始化。如果有参数,那就是用户自己编写的构造函数。

       4、“=”是对象引用指向刚在堆里面创建的Vehicle对象。

       当然,如果你只是声明一个对象的话,Vehicle veh1,其实只相当于声明了一个对象的引用部分,而引用是存储在堆中的,这时声明的对象为NULL。只有当你new一个对象时,编译器读到new的代码时,才会在堆中为你分配对象的内存地址,这时才是一个完整的对象。

       二、封装和继承

       封装和继承是面向对象语言区分于面向过程很重要的一个区别。
       所谓的封装,我理解的是,它对外隐藏了自己内部的东西,隐藏对象的属性和实现细节,仅对外提供访问方式,比如说接口。这样做的好处是什么呢?
       1、减少耦合。
       2、类内部的实现可以自由的修改。
       3、具有清晰的接口。
       继承,我的理解是,子类通过调用父类来实现重复代码的利用。子类不仅仅只继承父类的所有特征,还可以定义新的特征。这个很像UML里面的泛化,如图所示:
                                   
                               
       Animal就是顶层的一个父类,也叫基类,Dog,Cat,Fish就是它的子类,也叫做派生类。通过继承可以实现代码的重用,提高代码重用率,但是过度的使用继承也是有坏处的,继承的层次最好不要超过三层,不然类和类之间的耦合度会增加,不利于类的修改,尤其是对于顶层的类,可以说是牵一发而动全身。

       三、多态

       多态是面向对象中很重要的一个特征,是必须要建立在继承的基础上的。所谓多态就是同一操作作用于不同的对象,可以有不用的解释,产生不同的执行结果。C#中的多态分为两种,一种是编译时的多态性,一种是运行时的多态性。
       编译时多态:主要通过重载来实现,对于非虚成员来说,系统在编译时,根据传递的参数、返回的类型来决定进行何种操作。
       运行时多态:指直到系统运行时,才根据实际情况决定实现何种操作,C#中运行时的多态主要是通过重写虚成员来实现。
       下面举个简单的例子:
                                      
       如上图所示:shape是一个基类,它有自己的虚方法Draw()用来绘制图形,然后子类circle、rectangle、line继承父类的Draw()虚方法成员,并且重写了该方法,分别实现画圆、画矩形和画线条的功能。子类继承父类的相同的方法,却实现了具有自己特征的不同功能,产生不同的结果。这就是一个简单的多态的例子。当然,多态还有其他的表现方法,但自己现在的理解有限,等看完了设计模式,估计就可以有一个成型的体系了。

       四、抽象类和接口

       抽象是面向对象中很重要的思想,要想写出类来,首先就是抽象,比如猫、狗、牛、羊,都可以抽象出来一个共同的类,那就是动物。但是动物这个类是不适合实例化的,这种实例化没有任何意义。难道说这个世界上存在一种叫动物的对象吗?很显然,这种实体是不存在的。对于这种实例化没有意义的父类就应该改成抽象类了,这也是位于相对来说顶层的类使用的方法,抽象类不是用来实例的,而是派生 类的,也就是被继承。
       C#中的抽象类是用abstranct来修饰的,在UML类图中,抽象类被表示为斜体字,以区别对待于普通的类。抽象类只是声明抽象方法,却不实现。这些方法提供给子类,而子类也必须要实现所有的抽象方法。它跟多态还不同,多态是在基类里面有虚方法成员,有具体的实现,子类继承父类并重写该方法。
       介绍完了抽象类,接下来是另一个重头戏:接口
       接口是一个很灵活的东西,它的灵活性也导致它存在着很多的约束。接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合。一旦类实现了接口,类就可以支持接口所指定的所有属性和成员,但是接口是不允许实例化的。接口里面的方法和抽象方法一样,实现接口的类必须要实现接口中所有的方法和属性。C#中的接口用interface来修饰。
       接口的优点除了灵活以外,还有一个优点就是实现了类的多继承。关于类的多继承这块内容,自认为理解的不是很到位,这个还要跟C++语言去对比,这里就不在详细介绍了。推荐一篇文章:论C#之多继承。

       抽象类和接口之间的区别:
       抽象类和接口的共同点是都有必须在子类中实现的方法。抽象类除了抽象方法以外,还可以有非抽象的方法;而接口都是未实现的方法,并且接口可以实现类的多继承。

       总结:

       最后再总结一下面向对象和面向过程的区别。面向对象的主要目的还是封装和多态,可以增强各模块之间的内聚性,减少耦合性;面向过程即使面向对象里面封装的具体实现,注重的是功能的实现过程。所以我感觉他们之间更像是黑盒和白盒。面向对象是黑盒,注重功能;面向过程是白盒,注重内容的具体实现。这也只是个人的看法,有不妥的地方还行指出!
1 0